1
- import { useState } from ' react' ;
1
+ import { useState , useEffect } from ' react' ;
2
2
import { Meta , Story , Canvas , ArgsTable } from ' @storybook/addon-docs' ;
3
3
import { Combobox , CreatableCombobox , ComboboxOption } from ' @strapi/design-system' ;
4
4
5
5
<Meta title = " Design System/Components/Combobox" component = { Combobox } />
6
6
7
7
# Combobox
8
8
9
+ An input field designed to not only offer users the ability to type the value they want,
10
+ but also display a panel of suggestions which filter & autocomplete as the user types for a
11
+ more fluid experience. This shouldn't be confused with the [ ` Select ` ] ( /docs/design-system-components-select--basic )
12
+ component!
13
+
9
14
[ View source] ( https://github.com/strapi/design-system/tree/main/packages/strapi-design-system/src/Combobox )
10
15
11
- ## Imports
16
+ ## Usage
12
17
13
18
``` js
14
- import { Combobox } from ' @strapi/design-system' ;
19
+ import { Combobox , ComboboxOption , CreatableCombobox } from ' @strapi/design-system' ;
15
20
```
16
21
17
- ## Usage
18
-
19
- This ` Combobox ` can be found in forms. They give users to search and choose a value from given options.
20
-
21
- ### Base
22
+ ### Basic Usage
22
23
23
- In addition ` Combobox ` can also include a placeholder and a description line.
24
+ By default, the combobox uses both inline and list autocomplete, that is where as the user types suggestions
25
+ (based on the order of the options) are shown in the input field whilst the list gradually gets filtered.
24
26
25
27
<Canvas >
26
- <Story name = " base " >
28
+ <Story name = " basic " >
27
29
{ () => {
28
30
const [value, setValue] = useState (' ' );
29
31
return (
30
- <Combobox label = " Food" value = { value } onChange = { setValue } >
31
- <ComboboxOption value = " hamburger" >Hamburger</ComboboxOption >
32
- <ComboboxOption value = " bagel" >Bagel</ComboboxOption >
33
- <ComboboxOption value = " tartuffo" >Tartuffo</ComboboxOption >
34
- <ComboboxOption value = " carbonara" >Carbonara</ComboboxOption >
32
+ <Combobox
33
+ placeholder = " My favourite fruit is..."
34
+ label = " Fruits"
35
+ value = { value }
36
+ onChange = { setValue }
37
+ onClear = { () => setValue (' ' )}
38
+ >
39
+ <ComboboxOption value = " apple" >Apple</ComboboxOption >
40
+ <ComboboxOption value = " avocado" >Avocado</ComboboxOption >
41
+ <ComboboxOption value = " banana" >Banana</ComboboxOption >
42
+ <ComboboxOption value = " kiwi" >Kiwi</ComboboxOption >
43
+ <ComboboxOption value = " mango" >Mango</ComboboxOption >
44
+ <ComboboxOption value = " orange" >Orange</ComboboxOption >
45
+ <ComboboxOption value = " strawberry" >Strawberry</ComboboxOption >
35
46
</Combobox >
36
47
);
37
48
}}
38
49
</Story >
39
50
</Canvas >
40
51
41
- ### Disabled
52
+ ### Async data
42
53
43
- Depending on the permissions a user have or the status of an action, a ` Combobox ` can be unreachable or unavailable yet.
54
+ In some situations it might not be optimal to load all the data at once. In this case,
55
+ you can use the ` loading ` prop to load more data when the user scrolls to the bottom of the list.
44
56
45
- <Canvas >
46
- <Story name = " disabled" >
47
- { () => {
48
- const [value, setValue] = useState (' ' );
49
- return (
50
- <Combobox label = " Food" disabled value = { value } onChange = { setValue } >
51
- <ComboboxOption value = " hamburger" >Hamburger</ComboboxOption >
52
- <ComboboxOption value = " bagel" >Bagel</ComboboxOption >
53
- <ComboboxOption value = " tartuffo" >Tartuffo</ComboboxOption >
54
- <ComboboxOption value = " carbonara" >Carbonara</ComboboxOption >
55
- </Combobox >
56
- );
57
- }}
58
- </Story >
59
- </Canvas >
60
-
61
- ### Without label
62
-
63
- ` Combobox ` can be used without a label.
57
+ NOTE! You also need to supply an ` onLoadMore ` callback as well as defining if ` hasMoreItems `
58
+ is true to show the spinner. In future iterations, we plan to omit the ` hasMoreItems ` prop.
64
59
65
60
<Canvas >
66
- <Story name = " withoutLabel " >
61
+ <Story name = " loading " >
67
62
{ () => {
68
- const [value, setValue] = useState (' ' );
63
+ const [isLoading, setIsLoading] = useState (false );
64
+ const handleLoadMore = () => setIsLoading (true );
65
+ useEffect (() => {
66
+ if (isLoading ) {
67
+ const timeout = setTimeout (() => {
68
+ setIsLoading (false );
69
+ }, 2000 );
70
+ return () => clearTimeout (timeout );
71
+ }
72
+ }, [isLoading ]);
69
73
return (
70
- <Combobox aria-label = " Food" value = { value } onChange = { setValue } >
71
- <ComboboxOption value = " hamburger" >Hamburger</ComboboxOption >
72
- <ComboboxOption value = " bagel" >Bagel</ComboboxOption >
73
- <ComboboxOption value = " tartuffo" >Tartuffo</ComboboxOption >
74
- <ComboboxOption value = " carbonara" >Carbonara</ComboboxOption >
74
+ <Combobox
75
+ label = " Async Fruits"
76
+ placeholder = " My favourite fruit is..."
77
+ loading = { isLoading }
78
+ onLoadMore = { handleLoadMore }
79
+ hasMoreItems
80
+ >
81
+ <ComboboxOption value = " apple" >Apple</ComboboxOption >
82
+ <ComboboxOption value = " avocado" >Avocado</ComboboxOption >
83
+ <ComboboxOption value = " banana" >Banana</ComboboxOption >
84
+ <ComboboxOption value = " kiwi" >Kiwi</ComboboxOption >
85
+ <ComboboxOption value = " mango" >Mango</ComboboxOption >
86
+ <ComboboxOption value = " orange" >Orange</ComboboxOption >
87
+ <ComboboxOption value = " strawberry" >Strawberry</ComboboxOption >
75
88
</Combobox >
76
89
);
77
90
}}
78
91
</Story >
79
92
</Canvas >
80
93
81
- ### Error
94
+ ### Creating new options
82
95
83
- ` Combobox ` can display an error. The error message is customizable and replaces the description line below the input.
84
-
85
- <Canvas >
86
- <Story name = " error" >
87
- { () => {
88
- const [value, setValue] = useState (' ' );
89
- return (
90
- <Combobox label = " Food" value = { value } error = " An error occured" onChange = { setValue } >
91
- <ComboboxOption value = " hamburger" >Hamburger</ComboboxOption >
92
- <ComboboxOption value = " bagel" >Bagel</ComboboxOption >
93
- <ComboboxOption value = " tartuffo" >Tartuffo</ComboboxOption >
94
- <ComboboxOption value = " carbonara" >Carbonara</ComboboxOption >
95
- </Combobox >
96
- );
97
- }}
98
- </Story >
99
- </Canvas >
100
-
101
- ### Required
102
-
103
- ` Combobox ` can be required. The required state will appear with a red asterisk beside the label.
104
-
105
- <Canvas >
106
- <Story name = " required" >
107
- { () => {
108
- const [value, setValue] = useState (' ' );
109
- return (
110
- <Combobox label = " Food" value = { value } required onChange = { setValue } >
111
- <ComboboxOption value = " hamburger" >Hamburger</ComboboxOption >
112
- <ComboboxOption value = " bagel" >Bagel</ComboboxOption >
113
- <ComboboxOption value = " tartuffo" >Tartuffo</ComboboxOption >
114
- <ComboboxOption value = " carbonara" >Carbonara</ComboboxOption >
115
- </Combobox >
116
- );
117
- }}
118
- </Story >
119
- </Canvas >
120
-
121
- ### Initial data
122
-
123
- This is the doc of the ` Combobox ` component
124
-
125
- <Canvas >
126
- <Story name = " initial-data" >
127
- { () => {
128
- const [value, setValue] = useState (' tartuffo' );
129
- return (
130
- <Combobox label = " Food" value = { value } onChange = { setValue } >
131
- <ComboboxOption value = " hamburger" >Hamburger</ComboboxOption >
132
- <ComboboxOption value = " bagel" >Bagel</ComboboxOption >
133
- <ComboboxOption value = " tartuffo" >Tartuffo</ComboboxOption >
134
- <ComboboxOption value = " carbonara" >Carbonara</ComboboxOption >
135
- </Combobox >
136
- );
137
- }}
138
- </Story >
139
- </Canvas >
140
-
141
- ### Creatable
142
-
143
- The creatable mode of ` Combobox ` allows the creation of a new options.
96
+ If you want to allow users to create new options, you can use the ` CreatableCombobox ` component. This is
97
+ just a wrapper around the ` Combobox ` component that pre-flags the ` creatable ` prop as ` true ` . You should
98
+ still pass an ` onCreateOption ` callback to handle the creation of the new option.
144
99
145
100
<Canvas >
146
101
<Story name = " creatable" >
147
102
{ () => {
148
103
const [value, setValue] = useState (' ' );
149
104
const [options, setOptions] = useState ([
150
105
{
151
- name: ' Hamburger' ,
152
- value: ' hamburger' ,
153
- },
154
- {
155
- name: ' Hambu' ,
156
- value: ' hambu' ,
157
- },
158
- {
159
- name: ' Ham' ,
160
- value: ' ham' ,
161
- },
162
- {
163
- name: ' Sandwich' ,
164
- value: ' sandwich' ,
165
- },
166
- {
167
- name: ' Peperroni' ,
168
- value: ' peperroni' ,
106
+ name: ' Apple' ,
107
+ value: ' apple' ,
169
108
},
170
109
{
171
- name: ' Asparagus ' ,
172
- value: ' asparagus ' ,
110
+ name: ' Avocado ' ,
111
+ value: ' avocado ' ,
173
112
},
174
113
{
175
- name: ' Lettuce ' ,
176
- value: ' lettuce ' ,
114
+ name: ' Banana ' ,
115
+ value: ' banana ' ,
177
116
},
178
117
{
179
- name: ' Tomato ' ,
180
- value: ' tomato ' ,
118
+ name: ' Kiwi ' ,
119
+ value: ' kiwi ' ,
181
120
},
182
121
{
183
- name: ' Bagel ' ,
184
- value: ' bagel ' ,
122
+ name: ' Mango ' ,
123
+ value: ' mango ' ,
185
124
},
186
125
{
187
- name: ' Tartuffo ' ,
188
- value: ' tartuffo ' ,
126
+ name: ' Orange ' ,
127
+ value: ' orange ' ,
189
128
},
190
129
{
191
- name: ' Carbonara ' ,
192
- value: ' carbonara ' ,
130
+ name: ' Strawberry ' ,
131
+ value: ' strawberry ' ,
193
132
},
194
133
]);
195
134
const onCreateOption = (value ) => {
196
135
setOptions ((opt ) => [... opt , { name: value , value }]);
197
136
setValue (value );
198
137
};
199
138
return (
200
- <CreatableCombobox label = " Food" value = { value } onChange = { setValue } onCreateOption = { onCreateOption } >
139
+ <CreatableCombobox
140
+ label = " Fruits"
141
+ placeholder = " My favourite fruit is..."
142
+ value = { value }
143
+ onChange = { setValue }
144
+ onCreateOption = { onCreateOption }
145
+ >
201
146
{ options .map (({ name , value }) => (
202
147
<ComboboxOption key = { value } value = { value } >
203
148
{ name }
@@ -211,4 +156,14 @@ The creatable mode of `Combobox` allows the creation of a new options.
211
156
212
157
## Props
213
158
159
+ ### Combobox
160
+
214
161
<ArgsTable of = { Combobox } />
162
+
163
+ ### ComboboxOption
164
+
165
+ <ArgsTable of = { ComboboxOption } />
166
+
167
+ ### CreatableCombobox
168
+
169
+ <ArgsTable of = { CreatableCombobox } />
0 commit comments