@splunk/react-ui 5.7.1 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/Accordion.js +6 -6
  2. package/Box.js +83 -34
  3. package/CHANGELOG.md +29 -0
  4. package/CollapsiblePanel.js +11 -11
  5. package/ComboBox.js +31 -27
  6. package/ControlGroup.js +92 -91
  7. package/DefinitionList.js +9 -9
  8. package/Drawer.d.ts +2 -0
  9. package/Drawer.js +679 -0
  10. package/DualListbox.js +1 -1
  11. package/JSONTree.js +73 -72
  12. package/Link.js +2 -2
  13. package/MIGRATION.md +10 -0
  14. package/Menu.js +338 -240
  15. package/Modal.js +127 -109
  16. package/Multiselect.js +437 -351
  17. package/Paginator.js +14 -12
  18. package/Popover.js +4 -1
  19. package/README.md +11 -0
  20. package/RadioBar.js +1 -1
  21. package/Search.js +103 -88
  22. package/Select.js +42 -40
  23. package/SelectBase.js +374 -328
  24. package/SidePanel.js +346 -167
  25. package/SlidingPanels.js +11 -11
  26. package/StepBar.js +7 -7
  27. package/Switch.js +5 -5
  28. package/Text.js +24 -24
  29. package/TextArea.js +7 -7
  30. package/TransitionOpen.js +188 -169
  31. package/docs-llm/Accordion.md +267 -0
  32. package/docs-llm/Anchor Menu.md +115 -0
  33. package/docs-llm/Anchor.md +54 -0
  34. package/docs-llm/AnimationToggle.md +254 -0
  35. package/docs-llm/Avatar.md +298 -0
  36. package/docs-llm/Badge.md +212 -0
  37. package/docs-llm/Breadcrumbs.md +306 -0
  38. package/docs-llm/Button Group.md +53 -0
  39. package/docs-llm/Button.md +361 -0
  40. package/docs-llm/Card Layout.md +286 -0
  41. package/docs-llm/Card.md +619 -0
  42. package/docs-llm/Checkbox.md +218 -0
  43. package/docs-llm/Chip.md +291 -0
  44. package/docs-llm/Clickable.md +160 -0
  45. package/docs-llm/Code.md +292 -0
  46. package/docs-llm/Collapsible Panel.md +744 -0
  47. package/docs-llm/Color.md +253 -0
  48. package/docs-llm/Column Layout.md +391 -0
  49. package/docs-llm/Combo Box.md +540 -0
  50. package/docs-llm/Control Group.md +594 -0
  51. package/docs-llm/Date.md +270 -0
  52. package/docs-llm/Definition List.md +278 -0
  53. package/docs-llm/Divider.md +216 -0
  54. package/docs-llm/Drawer.md +414 -0
  55. package/docs-llm/Dropdown.md +472 -0
  56. package/docs-llm/Dual Listbox.md +325 -0
  57. package/docs-llm/File.md +653 -0
  58. package/docs-llm/Form Rows.md +374 -0
  59. package/docs-llm/Heading.md +179 -0
  60. package/docs-llm/Image.md +109 -0
  61. package/docs-llm/JSON Tree.md +260 -0
  62. package/docs-llm/Layer.md +74 -0
  63. package/docs-llm/Layout.md +50 -0
  64. package/docs-llm/Link.md +318 -0
  65. package/docs-llm/List.md +189 -0
  66. package/docs-llm/Markdown.md +179 -0
  67. package/docs-llm/Menu.md +735 -0
  68. package/docs-llm/Message Bar.md +236 -0
  69. package/docs-llm/Message.md +248 -0
  70. package/docs-llm/Modal.md +443 -0
  71. package/docs-llm/Monogram.md +159 -0
  72. package/docs-llm/Multiselect.md +937 -0
  73. package/docs-llm/Number.md +298 -0
  74. package/docs-llm/Paginator.md +395 -0
  75. package/docs-llm/Paragraph.md +148 -0
  76. package/docs-llm/Phone Number.md +254 -0
  77. package/docs-llm/Popover.md +166 -0
  78. package/docs-llm/Progress.md +141 -0
  79. package/docs-llm/Radio Bar.md +303 -0
  80. package/docs-llm/Radio List.md +350 -0
  81. package/docs-llm/Resize.md +362 -0
  82. package/docs-llm/Screen Reader Content.md +73 -0
  83. package/docs-llm/Scroll Container Context.md +155 -0
  84. package/docs-llm/Scroll.md +152 -0
  85. package/docs-llm/Search.md +381 -0
  86. package/docs-llm/Select.md +985 -0
  87. package/docs-llm/Side Panel.md +777 -0
  88. package/docs-llm/Slider.md +339 -0
  89. package/docs-llm/Sliding Panels.md +340 -0
  90. package/docs-llm/Split Button.md +295 -0
  91. package/docs-llm/Static Content.md +90 -0
  92. package/docs-llm/Step Bar.md +292 -0
  93. package/docs-llm/Switch.md +268 -0
  94. package/docs-llm/Tab Bar.md +439 -0
  95. package/docs-llm/Tab Layout.md +398 -0
  96. package/docs-llm/Table.md +2642 -0
  97. package/docs-llm/Text Area.md +253 -0
  98. package/docs-llm/Text.md +339 -0
  99. package/docs-llm/Tooltip.md +325 -0
  100. package/docs-llm/Transition Open.md +406 -0
  101. package/docs-llm/Tree.md +586 -0
  102. package/docs-llm/Typography.md +125 -0
  103. package/docs-llm/Wait Spinner.md +121 -0
  104. package/docs-llm/llms.txt +97 -0
  105. package/package.json +6 -5
  106. package/types/src/Box/Box.d.ts +2 -10
  107. package/types/src/Drawer/Body.d.ts +17 -0
  108. package/types/src/Drawer/Drawer.d.ts +114 -0
  109. package/types/src/Drawer/DrawerContext.d.ts +11 -0
  110. package/types/src/Drawer/Footer.d.ts +25 -0
  111. package/types/src/Drawer/Header.d.ts +41 -0
  112. package/types/src/Drawer/docs/examples/Basic.d.ts +6 -0
  113. package/types/src/Drawer/docs/examples/ContainerPosition.d.ts +7 -0
  114. package/types/src/Drawer/docs/examples/InitialFocus.d.ts +9 -0
  115. package/types/src/Drawer/docs/examples/InlinePosition.d.ts +7 -0
  116. package/types/src/Drawer/docs/examples/PagePosition.d.ts +7 -0
  117. package/types/src/Drawer/index.d.ts +2 -0
  118. package/types/src/JSONTree/JSONTree.d.ts +12 -5
  119. package/types/src/JSONTree/renderTreeItems.d.ts +2 -1
  120. package/types/src/Menu/Item.d.ts +2 -1
  121. package/types/src/Menu/docs/examples/SelectableCheckbox.d.ts +7 -0
  122. package/types/src/Modal/Modal.d.ts +1 -2
  123. package/types/src/Select/Option.d.ts +6 -3
  124. package/types/src/Select/Select.d.ts +8 -5
  125. package/types/src/Select/docs/examples/Dimmed.d.ts +7 -0
  126. package/types/src/SelectBase/OptionBase.d.ts +6 -3
  127. package/types/src/SelectBase/SelectBase.d.ts +8 -3
  128. package/types/src/SidePanel/SidePanel.d.ts +43 -2
  129. package/types/src/SidePanel/docs/examples/DockLayout.d.ts +17 -0
  130. package/types/src/SidePanel/docs/examples/InitialFocus.d.ts +9 -0
  131. package/types/src/TransitionOpen/TransitionOpen.d.ts +29 -4
  132. package/types/src/useKeyPress/index.d.ts +9 -2
  133. package/types/src/useOnClickOutside/index.d.ts +2 -0
  134. package/types/src/useOnClickOutside/useOnClickOutside.d.ts +4 -0
  135. package/useKeyPress.js +23 -18
  136. package/useOnClickOutside.d.ts +2 -0
  137. package/useOnClickOutside.js +79 -0
  138. package/types/src/RadioList/docs/examples/Row.d.ts +0 -6
@@ -0,0 +1,540 @@
1
+ # Combo Box
2
+
3
+ ## Overview
4
+
5
+
6
+
7
+ > Image: Illustration of a combo box component.
8
+
9
+
10
+ <Message appearance="fill" type="info">
11
+ <div>All data entry components should be wrapped in a <Link to="ControlGroup">Control Group</Link> to provide a label, error states, and help or error text, ensuring an accessible experience for all users.</div>
12
+ </Message>
13
+
14
+ ## When to use this component
15
+ - User needs to select from a large list of options.
16
+ - User needs to search and filter options within a list.
17
+ - Users need the flexibility to enter custom values in addition to selecting options from a list.
18
+ - Users know what they’re looking for and can enter enough characters to refine their search.
19
+
20
+ ## When to use another component
21
+ - Use a Radio List or Switch(Checkbox) for a small list of predefined options.
22
+ - Use a Select when the list of options is short, well-defined, and clearly distinct from each other. If the user needs to browse through values, a Select is more appropriate
23
+ - User needs to select multiple options or needs to create a custom value in addition to selecting multiple options from a list, use Multiselect.
24
+ - Use a Text for free-form input.
25
+
26
+ ```mermaid
27
+ graph TD
28
+ accDescr: Decision tree that guides on when to use the ComboBox component or something else
29
+ A(Are there less than 8 options?) -- Yes --- B(Radio or Checkbox group)
30
+ A -- No --- C(Well-defined list of options?)
31
+ C -- Yes --- D(Select)
32
+ C -- No --- E(Do users need to select multiple options?)
33
+ E -- No --- F(Combo Box)
34
+ E -- Yes --- G(Multiselect)
35
+ ```
36
+
37
+ ### Check out
38
+ - [Radio List][1]
39
+ - [Switch] [2]
40
+ - [Select][3]
41
+ - [Multiselect][4]
42
+ - [Text][5]
43
+
44
+ ## Behaviors
45
+
46
+ ### Custom values
47
+ Allow users to enter custom values not present in the predefined list.
48
+ > Image: Image showing an examples of the Combo box component with a custom value, Custom chart, typed in the input box.
49
+
50
+
51
+ ### Matching
52
+ Assist users in finding options quickly by providing matches and/or recommendations
53
+ > Image: Image showing a Combo box component in a focus state with the word chart typed in the input box, resulting in the list of options being filtered to only show options that have the word chart in the title.
54
+
55
+
56
+
57
+ ## Usage
58
+ ### Make large lists easier to search
59
+ The list of selections is complex enough to require searching and filtering capabilities. If the list is not extensive enough to justify a combo box, consider using a different selection method.
60
+ > Image: Two examples of Combo boxes. The first example with heart eyes emoji has a combo box labeled
61
+
62
+
63
+
64
+ ## Content guidelines
65
+ ### Keep menu items concise
66
+ Menu items should be clear and concise. Avoid menu items that wrap to multiple lines. Instead, use shorter text or increase the menu width when space allows.
67
+ > Image: Two examples of Combo boxes, both are labeled
68
+
69
+
70
+ ### Truncation
71
+ Use a width that accommodates the majority of options when possible.
72
+ > Image: Two examples of Combo boxes, both are labeled
73
+
74
+
75
+ [1]: ./RadioList
76
+ [2]: ./Switch
77
+ [3]: ./Select
78
+ [4]: ./Multiselect
79
+ [5]: ./Text
80
+
81
+ ## Examples
82
+
83
+
84
+ ### Uncontrolled
85
+
86
+ This is a basic example in which data management and filtering are handled internally.
87
+
88
+ ```typescript
89
+ import React from 'react';
90
+
91
+ import ComboBox from '@splunk/react-ui/ComboBox';
92
+
93
+
94
+ function Uncontrolled() {
95
+ return (
96
+ <ComboBox inline>
97
+ <ComboBox.Option value="Line Chart" description="Recommended" />
98
+ <ComboBox.Option value="Area Chart" />
99
+ <ComboBox.Option value="Column Chart" />
100
+ <ComboBox.Option value="Bar Chart" />
101
+ <ComboBox.Option value="Pie Chart" />
102
+ <ComboBox.Option value="Scatter Chart" />
103
+ <ComboBox.Option value="Bubble Chart" />
104
+ </ComboBox>
105
+ );
106
+ }
107
+
108
+ export default Uncontrolled;
109
+ ```
110
+
111
+
112
+
113
+ ### Headings
114
+
115
+ ```typescript
116
+ import React from 'react';
117
+
118
+ import ComboBox from '@splunk/react-ui/ComboBox';
119
+
120
+
121
+ export default function Headings() {
122
+ return (
123
+ <ComboBox inline>
124
+ <ComboBox.Option value="Events" />
125
+ <ComboBox.Option value="Statistics Table" />
126
+ <ComboBox.Heading>Chart</ComboBox.Heading>
127
+ <ComboBox.Option value="Line Chart" />
128
+ <ComboBox.Option value="Area Chart" />
129
+ <ComboBox.Option value="Column Chart" />
130
+ <ComboBox.Option value="Bar Chart" />
131
+ <ComboBox.Option value="Pie Chart" />
132
+ <ComboBox.Option value="Scatter Chart" />
133
+ <ComboBox.Option value="Bubble Chart" />
134
+ <ComboBox.Heading>Value</ComboBox.Heading>
135
+ <ComboBox.Option value="Single Value" />
136
+ <ComboBox.Option value="Radial Gauge" />
137
+ <ComboBox.Option value="Filler Gauge" />
138
+ <ComboBox.Option value="Marker Gauge" />
139
+ <ComboBox.Heading>Map</ComboBox.Heading>
140
+ <ComboBox.Option value="Cluster Map" />
141
+ <ComboBox.Option value="Choropleth Map" />
142
+ </ComboBox>
143
+ );
144
+ }
145
+ ```
146
+
147
+
148
+
149
+ ### Controlled Value
150
+
151
+ Typically, the value is controlled.
152
+
153
+ ```typescript
154
+ import React, { useState } from 'react';
155
+
156
+ import ComboBox, { ComboBoxChangeHandler } from '@splunk/react-ui/ComboBox';
157
+
158
+
159
+ function Controlled() {
160
+ const [value, setValue] = useState('');
161
+
162
+ const handleChange: ComboBoxChangeHandler = (e, { value: comboBoxValue }) => {
163
+ setValue(comboBoxValue);
164
+ };
165
+
166
+ return (
167
+ <ComboBox inline onChange={handleChange} value={value}>
168
+ <ComboBox.Option value="Line Chart" description="Recommended" />
169
+ <ComboBox.Option value="Area Chart" />
170
+ <ComboBox.Option value="Column Chart" />
171
+ <ComboBox.Option value="Bar Chart" />
172
+ <ComboBox.Option value="Pie Chart" />
173
+ <ComboBox.Option value="Scatter Chart" />
174
+ <ComboBox.Option value="Bubble Chart" />
175
+ </ComboBox>
176
+ );
177
+ }
178
+
179
+ export default Controlled;
180
+ ```
181
+
182
+
183
+
184
+ ### Label
185
+
186
+ label can be used in addition to value when needed, similar to Select. label will be used for matching and must be a string.
187
+
188
+ ```typescript
189
+ import React, { useState } from 'react';
190
+
191
+ import ComboBox, { ComboBoxChangeHandler } from '@splunk/react-ui/ComboBox';
192
+ import ControlGroup from '@splunk/react-ui/ControlGroup';
193
+
194
+
195
+ function Label() {
196
+ const [value, setValue] = useState('');
197
+
198
+ const handleChange: ComboBoxChangeHandler = (e, { value: comboBoxValue }) => {
199
+ setValue(comboBoxValue);
200
+ };
201
+
202
+ return (
203
+ <>
204
+ <ControlGroup label="Controlled" labelPosition="top">
205
+ <ComboBox inline onChange={handleChange} value={value}>
206
+ <ComboBox.Option value="chart-1" label="Line Chart" description="Recommended" />
207
+ <ComboBox.Option value="chart-2" label="Area Chart" />
208
+ <ComboBox.Option value="chart-3" label="Column Chart" />
209
+ <ComboBox.Option value="chart-4" label="Bar Chart" />
210
+ <ComboBox.Option value="chart-5" label="Pie Chart" />
211
+ <ComboBox.Option value="chart-6" label="Scatter Chart" />
212
+ <ComboBox.Option value="chart-7" label="Bubble Chart" />
213
+ </ComboBox>
214
+ </ControlGroup>
215
+
216
+ <ControlGroup label="Uncontrolled" labelPosition="top">
217
+ <ComboBox inline>
218
+ <ComboBox.Option value="chart-1" label="Line Chart" description="Recommended" />
219
+ <ComboBox.Option value="chart-2" label="Area Chart" />
220
+ <ComboBox.Option value="chart-3" label="Column Chart" />
221
+ <ComboBox.Option value="chart-4" label="Bar Chart" />
222
+ <ComboBox.Option value="chart-5" label="Pie Chart" />
223
+ <ComboBox.Option value="chart-6" label="Scatter Chart" />
224
+ <ComboBox.Option value="chart-7" label="Bubble Chart" />
225
+ </ComboBox>
226
+ </ControlGroup>
227
+ </>
228
+ );
229
+ }
230
+
231
+ export default Label;
232
+ ```
233
+
234
+
235
+
236
+ ### Fetching
237
+
238
+ You can populate the Options from a server. Here, that behavior is simulated. This simplified example only matches the start of the label. The matchRange prop can be set manually to reflect the matching algorithm used to filter the results. Otherwise matching text is not shown.
239
+
240
+ ```typescript
241
+ import React, { useCallback, useEffect, useState } from 'react';
242
+
243
+ import ComboBox, { ComboBoxChangeHandler } from '@splunk/react-ui/ComboBox';
244
+ import useFetchOptions, { MovieOption } from '@splunk/react-ui/fixtures/useFetchOptions';
245
+ import { _ } from '@splunk/ui-utils/i18n';
246
+
247
+
248
+ function Fetching() {
249
+
250
+ const { fetch, getFullCount, stop } = useFetchOptions();
251
+
252
+ const [fullCount, setFullCount] = useState(0);
253
+ const [isLoading, setIsLoading] = useState(false);
254
+ const [options, setOptions] = useState<MovieOption[]>([]);
255
+ const [value, setValue] = useState('');
256
+
257
+ const handleFetch = useCallback(
258
+ (comboBoxValue = '') => {
259
+ setValue(comboBoxValue);
260
+ setIsLoading(true);
261
+ fetch(comboBoxValue)
262
+ .then((comboBoxOptions) => {
263
+ setFullCount(getFullCount());
264
+ setIsLoading(false);
265
+ setOptions(comboBoxOptions);
266
+ })
267
+ .catch((error) => {
268
+ if (!error.isCanceled) {
269
+ throw error;
270
+ }
271
+ });
272
+ },
273
+ [fetch, getFullCount]
274
+ );
275
+
276
+ const generateOptions = () => {
277
+ if (isLoading) {
278
+ return null;
279
+ }
280
+
281
+ /*
282
+ * Filtering is done server-side and the `matchRanges` prop would be either
283
+ * be provided by the server, deduced based on the match algorithm, or omitted.
284
+ */
285
+ return options.map((movie) => (
286
+ <ComboBox.Option value={movie.title} key={movie.id} matchRanges={movie.matchRanges} />
287
+ ));
288
+ };
289
+
290
+ const footerMessage = () => {
291
+ if (fullCount > options.length && !isLoading) {
292
+ return _('%1 of %2 movies')
293
+ .replace('%1', options.length.toString())
294
+ .replace('%2', fullCount.toString());
295
+ }
296
+ return null;
297
+ };
298
+
299
+ const handleChange: ComboBoxChangeHandler = (e, { value: comboBoxValue }) => {
300
+ handleFetch(comboBoxValue);
301
+ };
302
+
303
+ useEffect(() => {
304
+ handleFetch();
305
+
306
+ return () => {
307
+ stop();
308
+ };
309
+ }, [handleFetch, stop]);
310
+
311
+ const comboBoxOptions = generateOptions();
312
+ const footerMessageValue = footerMessage();
313
+
314
+ return (
315
+ <ComboBox
316
+ value={value}
317
+ controlledFilter
318
+ inline
319
+ placeholder={_('Select a movie...')}
320
+ menuStyle={{ width: 300 }}
321
+ onChange={handleChange}
322
+ isLoadingOptions={isLoading}
323
+ footerMessage={footerMessageValue}
324
+ >
325
+ {comboBoxOptions}
326
+ </ComboBox>
327
+ );
328
+ }
329
+
330
+ export default Fetching;
331
+ ```
332
+
333
+
334
+
335
+ ### Load more on scroll bottom
336
+
337
+ Similar example to Fetching, but you can also append more Options from a server when the list is scrolled to the bottom. Here, that behavior is simulated. The onScrollBottom prop is a function that fetches more results and appends them to the current Options. Once all items are loaded, the onScrollBottom prop should be set to null.
338
+
339
+ ```typescript
340
+ import React, { useCallback, useEffect, useState } from 'react';
341
+
342
+ import ComboBox, { ComboBoxChangeHandler } from '@splunk/react-ui/ComboBox';
343
+ import useFetchOptions, { MovieOption } from '@splunk/react-ui/fixtures/useFetchOptions';
344
+ import { _ } from '@splunk/ui-utils/i18n';
345
+
346
+
347
+ const createFooterMessage = (loadingMore: string, count: string) => {
348
+ return _('%1 movies %2').replace('%1', loadingMore).replace('%2', count);
349
+ };
350
+
351
+ function LoadMoreOnScrollBottom() {
352
+ const [fullCount, setFullCount] = useState<number>(0);
353
+ const [isLoading, setIsLoading] = useState<boolean>(false);
354
+ const [isLoadingMore, setIsLoadingMore] = useState<boolean>(false);
355
+ const [options, setOptions] = useState<MovieOption[]>([]);
356
+ const [value, setValue] = useState<string>('');
357
+
358
+
359
+ const { fetch, fetchMore, getFullCount, stop } = useFetchOptions();
360
+
361
+ const handleFetch = useCallback(
362
+ (comboBoxValue = '') => {
363
+ setValue(comboBoxValue);
364
+ setIsLoading(true);
365
+
366
+ fetch(comboBoxValue)
367
+ .then((comboBoxOptions) => {
368
+ setOptions(comboBoxOptions);
369
+ setIsLoading(false);
370
+ setIsLoadingMore(false);
371
+ setFullCount(getFullCount());
372
+ })
373
+ .catch((error) => {
374
+ if (!error.isCanceled) {
375
+ throw error;
376
+ }
377
+ });
378
+ },
379
+ [fetch, getFullCount, setOptions]
380
+ );
381
+
382
+ const handleFetchMore = (currentOptions?: MovieOption[]) => {
383
+ setIsLoadingMore(true);
384
+
385
+ fetchMore(currentOptions)
386
+ .then((comboBoxOptions) => {
387
+ setOptions(comboBoxOptions);
388
+ setIsLoadingMore(false);
389
+ setIsLoadingMore(false);
390
+ setFullCount(getFullCount());
391
+ })
392
+ .catch((error) => {
393
+ if (!error.isCanceled) {
394
+ throw error;
395
+ }
396
+ });
397
+ };
398
+
399
+ const handleScrollBottom = () => {
400
+ if (!isLoadingMore) {
401
+ handleFetchMore(options);
402
+ }
403
+ };
404
+
405
+ const generateOptions = () => {
406
+ if (isLoading) {
407
+ return null;
408
+ }
409
+
410
+ /*
411
+ * Filtering is done server-side and the `matchRanges` prop would be either
412
+ * be provided by the server, deduced based on the match algorithm, or omitted.
413
+ */
414
+ return options.map((movie) => (
415
+ <ComboBox.Option value={movie.title} key={movie.id} matchRanges={movie.matchRanges} />
416
+ ));
417
+ };
418
+
419
+ useEffect(() => {
420
+ handleFetch();
421
+
422
+ return () => {
423
+ stop();
424
+ };
425
+ }, [setOptions, handleFetch, stop]);
426
+
427
+ const handleChange: ComboBoxChangeHandler = (e, { value: comboBoxValue }) => {
428
+ handleFetch(comboBoxValue);
429
+ };
430
+
431
+ const footerMessage = createFooterMessage(
432
+ fullCount.toString(),
433
+ isLoadingMore ? _('(Loading more movies)') : ''
434
+ );
435
+ const comboBoxOptions = generateOptions();
436
+
437
+ return (
438
+ <ComboBox
439
+ value={value}
440
+ controlledFilter
441
+ inline
442
+ placeholder={_('Select a movie...')}
443
+ menuStyle={{ width: 300 }}
444
+ onChange={handleChange}
445
+ onScrollBottom={
446
+ // Disable when all items are loaded.
447
+ fullCount === options.length ? undefined : handleScrollBottom
448
+ }
449
+ isLoadingOptions={isLoading}
450
+ footerMessage={footerMessage}
451
+ >
452
+ {comboBoxOptions}
453
+ </ComboBox>
454
+ );
455
+ }
456
+
457
+ export default LoadMoreOnScrollBottom;
458
+ ```
459
+
460
+
461
+
462
+
463
+ ## API
464
+
465
+
466
+ ### ComboBox API
467
+
468
+ `ComboBox` allows the user to select a predefined string or enter a new value. Unlike `Select`
469
+ and `Multiselect`, `Option` value must always be a string.
470
+
471
+ #### Props
472
+
473
+ | Name | Type | Required | Default | Description |
474
+ |------|------|------|------|------|
475
+ | animateLoading | boolean | no | | |
476
+ | append | boolean | no | | Append removes rounded borders and border from the right side. |
477
+ | children | React.ReactNode | no | | All children must be instances of `ComboBox.Option`. |
478
+ | controlledFilter | boolean | no | | If true, this component will not handle filtering. The parent must update the Options based on the onChange value. |
479
+ | defaultPlacement | 'above' \| 'below' \| 'vertical' | no | 'vertical' | The default placement of the dropdown menu. It might be rendered in a different direction depending upon the space available. |
480
+ | defaultValue | string | no | | The initial value of the input. Only applicable in uncontrolled mode. |
481
+ | describedBy | string | no | | The id of the description. When placed in a ControlGroup, this is automatically set to the ControlGroup's help component. |
482
+ | disabled | boolean | no | | |
483
+ | elementRef | React.Ref<HTMLDivElement> | no | | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
484
+ | error | boolean | no | | Highlight the field as having an error. The border and text will turn red. |
485
+ | footerMessage | React.ReactNode | no | | The footer message can show additional information, such as a truncation message. |
486
+ | inline | boolean | no | | Make the control an inline block with variable width. |
487
+ | inputId | string | no | | An id for the input, which may be necessary for accessibility, such as for aria attributes. |
488
+ | inputRef | React.Ref<HTMLInputElement> | no | | A React ref which is set to the input element when the component mounts and null when it unmounts. |
489
+ | isLoadingOptions | boolean | no | | |
490
+ | labelledBy | string | no | | The id of the label. When placed in a ControlGroup, this is automatically set to the ControlGroup's label. |
491
+ | loadingMessage | React.ReactNode | no | | The loading message to show when isLoadingOptions. |
492
+ | menuStyle | React.CSSProperties | no | {} | |
493
+ | name | string | no | | The name is returned with onChange events, which can be used to identify the control when multiple controls share an onChange callback. |
494
+ | noOptionsMessage | React.ReactNode | no | | The noOptionsMessage is shown when there are no children and it's not loading, such as when there are no Options matching the filter. This can be customized to the type of content, for example: "No matching dashboards". You can insert content such as an error message or communicate a minimum number of characters to enter to see results. |
495
+ | onBlur | ComboBoxBlurHandler | no | | |
496
+ | onChange | ComboBoxChangeHandler | no | | |
497
+ | onClose | () => void | no | | A callback function invoked when the popover closes. |
498
+ | onFocus | ComboBoxFocusHandler | no | | |
499
+ | onKeyDown | React.KeyboardEventHandler<HTMLInputElement> | no | | |
500
+ | onOpen | () => void | no | | A callback function invoked when the popover opens. |
501
+ | onScroll | React.UIEventHandler<Element> | no | | A callback function invoked when the menu is scrolled. |
502
+ | onScrollBottom | ComboBoxScrollBottomHandler | no | | A callback function for loading additional list items. Called when the list is scrolled to the bottom or all items in the list are visible. This is called with an event argument if this is the result of a scroll. This should be set this to `null` when all items are loaded. |
503
+ | onSelect | React.ReactEventHandler<HTMLInputElement> | no | | |
504
+ | placeholder | string | no | _('Select...') | |
505
+ | prepend | boolean | no | | Prepend removes rounded borders from the left side. |
506
+ | value | string | no | | The value of the input. Only applicable in controlled mode. |
507
+
508
+ #### Types
509
+
510
+ | Name | Type | Description |
511
+ |------|------|------|
512
+ | ComboBoxBlurHandler | ( event: React.FocusEvent<HTMLInputElement>, data: { name?: string; value: string; } ) => void | |
513
+ | ComboBoxChangeHandler | ( event: \| React.ChangeEvent<HTMLInputElement> \| React.MouseEvent<HTMLButtonElement \| HTMLSpanElement> \| React.KeyboardEvent<HTMLInputElement>, data: { name?: string; value: string; } ) => void | |
514
+ | ComboBoxFocusHandler | ( event: React.FocusEvent<HTMLInputElement>, data: { name?: string; value: string; } ) => void | |
515
+ | ComboBoxScrollBottomHandler | ( event: React.UIEvent<HTMLDivElement> \| React.KeyboardEvent<HTMLInputElement> \| null ) => void | |
516
+
517
+
518
+
519
+ ### ComboBox.Option API
520
+
521
+ An option within a `ComboBox`.
522
+
523
+ #### Props
524
+
525
+ | Name | Type | Required | Default | Description |
526
+ |------|------|------|------|------|
527
+ | description | string | no | | Additional information to explain the option, such as "Recommended". |
528
+ | descriptionPosition | 'right' \| 'bottom' | no | 'bottom' | The description text may appear to the right of the label or under the label. |
529
+ | disabled | boolean | no | | If disabled=true, the option is grayed out and cannot be clicked. |
530
+ | elementRef | React.Ref<HTMLButtonElement \| HTMLAnchorElement> | no | | A React ref which is set to the DOM element when the component mounts and null when it unmounts. |
531
+ | icon | React.ReactNode | no | | The icon to show before the label. See the @splunk/react-icons package for drop in icons. Caution: The element(s) passed here must be pure. All icons in the react-icons package are pure. |
532
+ | label | string | no | | When provided, `label` is rendered instead of the `value` and used for matching. |
533
+ | matchRanges | { start: number; end: number }[] | no | | Sections of the label string to highlight as a match. This is automatically set for uncontrolled filters, so it's not normally necessary to set this property when using filtering. |
534
+ | truncate | boolean | no | | When `true`, wrapping is disabled and any additional text is ellipsised. |
535
+ | value | string | yes | | The value of this option and the label shown for it. |
536
+
537
+
538
+
539
+
540
+