@onehat/ui 0.3.57 → 0.3.59

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.
@@ -12,37 +12,38 @@ import {
12
12
  } from '../../../../Constants/UiModes.js';
13
13
  import UiGlobals from '../../../../UiGlobals.js';
14
14
  import Input from '../Input.js';
15
+ import withAlert from '../../../Hoc/withAlert.js';
15
16
  import withComponent from '../../../Hoc/withComponent.js';
16
17
  import withData from '../../../Hoc/withData.js';
17
- import withSelection from '../../../Hoc/withSelection.js';
18
18
  import withValue from '../../../Hoc/withValue.js';
19
19
  import emptyFn from '../../../../Functions/emptyFn.js';
20
20
  import { Grid, WindowedGridEditor } from '../../../Grid/Grid.js';
21
21
  import IconButton from '../../../Buttons/IconButton.js';
22
22
  import CaretDown from '../../../Icons/CaretDown.js';
23
+ import Xmark from '../../../Icons/Xmark.js';
23
24
  import _ from 'lodash';
24
25
 
25
- // Combo requires the use of HOC withSelection() whenever it's used.
26
- // The default export is *with* the HOC. A separate *raw* component is
27
- // exported which can be combined with many HOCs for various functionality.
28
-
29
26
  export function ComboComponent(props) {
30
27
  const {
31
28
  additionalButtons,
32
29
  autoFocus = false,
33
- forceSelection = true,
34
30
  tooltipRef = null,
35
31
  tooltip = null,
36
32
  menuMinWidth = 150,
37
33
  disableDirectEntry = false,
38
34
  hideMenuOnSelection = true,
35
+ showXButton = false,
39
36
  _input = {},
40
37
  isEditor = false,
41
38
  isDisabled = false,
39
+ tooltipPlacement = 'bottom',
40
+ onRowPress,
42
41
 
43
- // withValue
44
- value,
45
- setValue,
42
+ // withComponent
43
+ self,
44
+
45
+ // withAlert
46
+ confirm,
46
47
 
47
48
  // withData
48
49
  Repository,
@@ -50,32 +51,28 @@ export function ComboComponent(props) {
50
51
  idIx,
51
52
  displayIx,
52
53
 
53
- // withSelection
54
- disableWithSelection,
55
- selection,
56
- setSelection,
57
- selectionMode,
58
- selectNext,
59
- selectPrev,
60
- getDisplayValuesFromSelection,
61
-
62
- tooltipPlacement = 'bottom',
54
+ // withValue
55
+ value,
56
+ setValue,
63
57
  } = props,
64
58
  styles = UiGlobals.styles,
65
59
  inputRef = useRef(),
66
60
  triggerRef = useRef(),
67
61
  menuRef = useRef(),
68
- isManuallyEnteringText = useRef(false),
62
+ displayValueRef = useRef(null),
69
63
  savedSearch = useRef(null),
70
64
  typingTimeout = useRef(),
71
65
  [isMenuShown, setIsMenuShown] = useState(false),
72
66
  [isRendered, setIsRendered] = useState(false),
73
- [textValue, setTextValue] = useState(''),
67
+ [isReady, setIsReady] = useState(false),
68
+ [isSearchMode, setIsSearchMode] = useState(false),
69
+ [gridSelection, setGridSelection] = useState(null),
70
+ [textInputValue, setTextInputValue] = useState(''),
71
+ [newEntityDisplayValue, setNewEntityDisplayValue] = useState(null),
74
72
  [width, setWidth] = useState(0),
75
- [height, setHeight] = useState(null),
76
73
  [top, setTop] = useState(0),
77
74
  [left, setLeft] = useState(0),
78
- showMenu = () => {
75
+ showMenu = async () => {
79
76
  if (isMenuShown) {
80
77
  return;
81
78
  }
@@ -107,7 +104,7 @@ export function ComboComponent(props) {
107
104
  }
108
105
  }
109
106
  if (Repository && !Repository.isLoaded) {
110
- Repository.reload();
107
+ await Repository.load();
111
108
  }
112
109
  setIsMenuShown(true);
113
110
  },
@@ -117,11 +114,8 @@ export function ComboComponent(props) {
117
114
  }
118
115
  setIsMenuShown(false);
119
116
  },
120
- getIsManuallyEnteringText = () => {
121
- return isManuallyEnteringText.current;
122
- },
123
- setIsManuallyEnteringText = (bool) => {
124
- isManuallyEnteringText.current = bool;
117
+ toggleMenu = () => {
118
+ setIsMenuShown(!isMenuShown);
125
119
  },
126
120
  getSavedSearch = () => {
127
121
  return savedSearch.current;
@@ -129,8 +123,8 @@ export function ComboComponent(props) {
129
123
  setSavedSearch = (val) => {
130
124
  savedSearch.current = val;
131
125
  },
132
- toggleMenu = () => {
133
- setIsMenuShown(!isMenuShown);
126
+ resetInputTextValue = () => {
127
+ setTextInputValue(getDisplayValue());
134
128
  },
135
129
  onInputKeyPress = (e, inputValue) => {
136
130
  if (disableDirectEntry) {
@@ -138,6 +132,8 @@ export function ComboComponent(props) {
138
132
  }
139
133
  switch(e.key) {
140
134
  case 'Escape':
135
+ setIsSearchMode(false);
136
+ resetInputTextValue();
141
137
  hideMenu();
142
138
  break;
143
139
  case 'Enter':
@@ -145,24 +141,42 @@ export function ComboComponent(props) {
145
141
  if (_.isEmpty(inputValue) && !_.isNull(value)) {
146
142
  // User pressed Enter on an empty text field, but value is set to something
147
143
  // This means the user cleared the input and pressed enter, meaning he wants to clear the value
148
-
149
- // clear the value
150
144
  setValue(null);
151
- if (isMenuShown) {
152
- hideMenu();
153
- }
154
- } else {
155
- toggleMenu();
145
+ hideMenu();
146
+ return;
147
+ }
148
+
149
+ if (_.isEmpty(gridSelection)) {
150
+ confirm('You have nothing selected in the dropdown menu. Clear value?', doIt, true);
151
+ return;
152
+ }
153
+
154
+ doIt();
155
+
156
+ function doIt() {
157
+ setValue(gridSelection?.id);
158
+ hideMenu();
156
159
  }
157
160
  break;
158
- case 'ArrowDown':
159
- e.preventDefault();
160
- selectNext();
161
- break;
162
- case 'ArrowUp':
163
- e.preventDefault();
164
- selectPrev();
165
- break;
161
+ // case 'ArrowDown':
162
+ // e.preventDefault();
163
+ // showMenu();
164
+ // selectNext();
165
+ // setTimeout(() => {
166
+ // if (!self.children?.dropdownGrid?.selectPrev) {
167
+ // debugger;
168
+ // }
169
+ // self.children.dropdownGrid.selectNext();
170
+ // }, 10);
171
+ // break;
172
+ // case 'ArrowUp':
173
+ // e.preventDefault();
174
+ // showMenu();
175
+ // selectPrev();
176
+ // setTimeout(() => {
177
+ // self.children.dropdownGrid.selectPrev();
178
+ // }, 10);
179
+ // break;
166
180
  default:
167
181
  }
168
182
  },
@@ -170,140 +184,142 @@ export function ComboComponent(props) {
170
184
  if (disableDirectEntry) {
171
185
  return;
172
186
  }
173
- setTextValue(value);
174
187
 
175
- setIsManuallyEnteringText(true);
188
+ if (_.isEmpty(value)) {
189
+ // text input is cleared
190
+ hideMenu();
191
+ return;
192
+ }
193
+
194
+ setTextInputValue(value);
195
+ showMenu();
196
+
176
197
  clearTimeout(typingTimeout.current);
177
198
  typingTimeout.current = setTimeout(() => {
178
199
  searchForMatches(value);
179
200
  }, 300);
180
201
  },
202
+ onInputFocus = (e) => {
203
+ inputRef.current.select();
204
+ },
181
205
  onInputBlur = (e) => {
182
- const {
183
- relatedTarget
184
- } = e;
185
-
186
- setIsManuallyEnteringText(false);
187
-
188
- // If user focused on the trigger and text is blank, clear the selection and close the menu
189
- if ((triggerRef.current === relatedTarget || triggerRef.current.contains(relatedTarget)) && (_.isEmpty(textValue) || _.isNil(textValue))) {
190
- if (!disableWithSelection) {
191
- setSelection([]); // delete current selection
192
- }
193
- hideMenu();
194
- return;
195
- }
196
-
197
- // If user focused on the menu or trigger, ignore this blur
198
- if (triggerRef.current === relatedTarget ||
199
- triggerRef.current.contains(relatedTarget) ||
200
- menuRef.current=== relatedTarget ||
201
- menuRef.current?.contains(relatedTarget)) {
206
+ if (isEventStillInComponent(e)) {
207
+ // ignore the blur
202
208
  return;
203
209
  }
204
210
 
205
- if (!relatedTarget ||
206
- (
207
- !inputRef.current.contains(relatedTarget) &&
208
- triggerRef.current !== relatedTarget &&
209
- (!menuRef.current || !menuRef.current.contains(relatedTarget))
210
- )
211
- ) {
212
- hideMenu();
213
- }
214
- if (_.isEmpty(textValue) || _.isNil(textValue)) {
215
-
216
- if (!disableWithSelection) {
217
- setSelection([]); // delete current selection
218
- }
219
-
220
- } else if (getIsManuallyEnteringText()) {
221
- if (forceSelection) {
222
- if (!disableWithSelection) {
223
- setSelection([]); // delete current selection
224
- } else {
225
- setValue(textValue);
226
- }
227
- hideMenu();
228
- } else {
229
- setValue(textValue);
230
- }
231
- }
232
-
233
- if (!disableWithSelection) {
234
- if (_.isEmpty(selection)) {
235
- setTextValue('');
236
- }
237
- }
211
+ setIsSearchMode(false);
212
+ resetInputTextValue();
213
+ hideMenu();
238
214
  },
239
- onInputClick = (e) => {
215
+ onTriggerPress = (e) => {
240
216
  if (!isRendered) {
241
217
  return;
242
218
  }
219
+ clearGridFilters();
243
220
  showMenu();
244
221
  },
245
- onTriggerPress = (e) => {
246
- if (!isRendered) {
222
+ onTriggerBlur = (e) => {
223
+ if (!isMenuShown) {
247
224
  return;
248
225
  }
249
- if (isMenuShown) {
250
- hideMenu();
251
- } else {
252
- showMenu();
226
+
227
+ if (isEventStillInComponent(e)) {
228
+ // ignore the blur
229
+ return;
253
230
  }
254
- inputRef.current.focus();
231
+
232
+ setIsSearchMode(false);
233
+ resetInputTextValue();
234
+ hideMenu();
255
235
  },
256
- onTriggerBlur = (e) => {
236
+ onClearBtn = () => {
237
+ setTextInputValue('');
238
+ setValue(null);
239
+ }
240
+ isEventStillInComponent = (e) => {
257
241
  const {
258
242
  relatedTarget
259
243
  } = e;
260
-
261
- if (!disableWithSelection) {
262
- if (_.isEmpty(textValue) || _.isNil(textValue)) {
263
- setSelection([]); // delete current selection
244
+ return !relatedTarget ||
245
+ !menuRef.current ||
246
+ !triggerRef.current ||
247
+ triggerRef.current === relatedTarget ||
248
+ triggerRef.current.contains(relatedTarget) ||
249
+ menuRef.current === relatedTarget ||
250
+ menuRef.current?.contains(relatedTarget);
251
+ },
252
+ clearGridFilters = async () => {
253
+ if (Repository) {
254
+ if (Repository.isLoading) {
255
+ await Repository.waitUntilDoneLoading();
264
256
  }
265
- }
257
+
258
+ // clear filter
259
+ if (Repository.isRemote) {
260
+ let searchField = 'q';
261
+ const searchValue = null;
266
262
 
267
- if (!isMenuShown) {
268
- return;
269
- }
270
- if (!relatedTarget ||
271
- (!inputRef.current.contains(relatedTarget) && triggerRef.current !== relatedTarget && !menuRef.current.contains(relatedTarget))) {
272
- hideMenu();
263
+ // Check to see if displayField is a real field
264
+ const
265
+ schema = Repository.getSchema(),
266
+ displayFieldName = schema.model.displayProperty,
267
+ displayFieldDef = schema.getPropertyDefinition(displayFieldName);
268
+ if (!displayFieldDef.isVirtual) {
269
+ searchField = displayFieldName + ' LIKE';
270
+ }
271
+
272
+ Repository.clear();
273
+ await Repository.filter(searchField, searchValue);
274
+ if (!this.isAutoLoad) {
275
+ await Repository.reload();
276
+ }
277
+
278
+ } else {
279
+ throw Error('Not yet implemented');
280
+ }
281
+
282
+ setSavedSearch(null);
283
+
284
+ } else {
285
+ // throw Error('Not yet implemented');
273
286
  }
274
287
  },
275
288
  searchForMatches = async (value) => {
276
-
277
- if (_.isEmpty(value)) {
278
- return;
289
+ if (!isMenuShown) {
290
+ showMenu();
279
291
  }
280
292
 
293
+ setIsSearchMode(true);
294
+
281
295
  let found;
282
296
  if (Repository) {
297
+ if (Repository.isLoading) {
298
+ await Repository.waitUntilDoneLoading();
299
+ }
283
300
 
284
301
  // Set filter
285
302
  let filter = {};
286
303
  if (Repository.isRemote) {
287
304
  let searchField = 'q';
305
+ const searchValue = _.isEmpty(value) ? null : value + '%';
288
306
 
289
307
  // Check to see if displayField is a real field
290
308
  const
291
309
  schema = Repository.getSchema(),
292
- displayFieldName = schema.model.displayProperty;
310
+ displayFieldName = schema.model.displayProperty,
293
311
  displayFieldDef = schema.getPropertyDefinition(displayFieldName);
294
312
  if (!displayFieldDef.isVirtual) {
295
313
  searchField = displayFieldName + ' LIKE';
296
314
  }
297
315
 
298
- value += '%';
299
-
300
- await Repository.filter(searchField, value);
316
+ await Repository.filter(searchField, searchValue);
301
317
  if (!this.isAutoLoad) {
302
318
  await Repository.reload();
303
319
  }
304
320
 
305
321
  } else {
306
- throw Error('Not sure if this works yet!');
322
+ throw Error('Not yet implemented');
307
323
 
308
324
  // Fuzzy search with getBy filter function
309
325
  filter = (entity) => {
@@ -316,18 +332,12 @@ export function ComboComponent(props) {
316
332
  }
317
333
 
318
334
  setSavedSearch(value);
319
- if (!disableWithSelection) {
320
- const numResults = Repository.entities.length;
321
- if (!numResults) {
322
- setSelection([]);
323
- } else if (numResults === 1) {
324
- const selection = Repository.entities[0];
325
- setSelection([selection]);
326
- setSavedSearch(null);
327
- }
328
- }
335
+ setNewEntityDisplayValue(value); // capture the search query so we can tell Grid what to use for a new entity's displayValue
329
336
 
330
337
  } else {
338
+
339
+ throw Error('Not yet implemented'); // NOTE: When implementing this, also implement clearGridFilters
340
+
331
341
  // Search through data
332
342
  found = _.find(data, (item) => {
333
343
  if (_.isString(item[displayIx]) && _.isString(value)) {
@@ -335,23 +345,64 @@ export function ComboComponent(props) {
335
345
  }
336
346
  return item[displayIx] === value;
337
347
  });
338
- if (found) {
339
- const
340
- newSelection = [found],
341
- newTextValue = getDisplayValuesFromSelection(newSelection);
348
+ // if (found) {
349
+ // const
350
+ // newSelection = [found];
342
351
 
343
- setTextValue(newTextValue);
344
- if (!disableWithSelection) {
345
- setSelection(newSelection);
352
+ // setTextInputValue(newTextValue);
353
+ // }
354
+ }
355
+ },
356
+ getDisplayValue = () => {
357
+ return displayValueRef.current;
358
+ },
359
+ setDisplayValue = async (value) => {
360
+ let displayValue = '';
361
+ if (_.isNil(value)) {
362
+ // do nothing
363
+ } else if (_.isArray(value)) {
364
+ displayValue = [];
365
+ if (Repository) {
366
+ if (!Repository.isLoaded) {
367
+ throw Error('Not yet implemented'); // Would a Combo ever have multiple remote selections? Shouldn't that be a Tag field??
346
368
  }
369
+ if (Repository.isLoading) {
370
+ await Repository.waitUntilDoneLoading();
371
+ }
372
+ displayValue = _.each(value, (id) => {
373
+ const entity = Repository.getById(id);
374
+ if (entity) {
375
+ displayValue.push(entity.displayValue)
376
+ }
377
+ });
347
378
  } else {
348
- if (value === '') { // Text field was cleared, so clear selection
349
- if (!disableWithSelection) {
350
- setSelection([]);
379
+ displayValue = _.each(value, (id) => {
380
+ const item = _.find(data, (datum) => datum[idIx] === id);
381
+ if (item) {
382
+ displayValue.push(item[displayIx]);
383
+ }
384
+ });
385
+ }
386
+ displayValue = displayValue.join(', ');
387
+ } else {
388
+ if (Repository) {
389
+ let entity;
390
+ if (!Repository.isLoaded) {
391
+ entity = await Repository.getSingleEntityFromServer(value);
392
+ } else {
393
+ if (Repository.isLoading) {
394
+ await Repository.waitUntilDoneLoading();
351
395
  }
396
+ entity = Repository.getById(value);
352
397
  }
398
+ displayValue = entity?.displayValue || '';
399
+ } else {
400
+ const item = _.find(data, (datum) => datum[idIx] === value);
401
+ displayValue = (item && item[displayIx]) || '';
353
402
  }
354
403
  }
404
+
405
+ displayValueRef.current = displayValue;
355
406
  };
356
407
 
357
408
  useEffect(() => {
@@ -365,30 +416,62 @@ export function ComboComponent(props) {
365
416
 
366
417
  }, [isRendered]);
367
418
 
368
- if (!disableWithSelection) {
369
- useEffect(() => {
370
- if (getIsManuallyEnteringText() && getSavedSearch()) {
371
- return
419
+ useEffect(() => {
420
+ (async () => {
421
+ setIsSearchMode(false);
422
+ await setDisplayValue(value);
423
+ resetInputTextValue();
424
+ if (!isReady) {
425
+ setIsReady(true);
372
426
  }
427
+ })();
428
+ }, [value]);
373
429
 
374
- // Adjust text input to match selection
375
- let localTextValue = getDisplayValuesFromSelection(selection);
376
- if (!_.isEqual(localTextValue, textValue)) {
377
- setTextValue(localTextValue);
378
- }
379
- setIsManuallyEnteringText(false);
380
- }, [selection]);
430
+ if (!isReady) {
431
+ return null;
381
432
  }
382
433
 
434
+ if (self) {
435
+ self.clear = onClearBtn;
436
+ }
383
437
 
384
438
  const refProps = {};
385
439
  if (tooltipRef) {
386
440
  refProps.ref = tooltipRef;
387
441
  }
388
442
 
443
+ const gridProps = _.pick(props, [
444
+ 'Editor',
445
+ 'model',
446
+ 'Repository',
447
+ 'data',
448
+ 'idIx',
449
+ 'displayIx',
450
+ 'value',
451
+ 'disableView',
452
+ 'disableCopy',
453
+ 'disableDuplicate',
454
+ 'disablePrint',
455
+ ]);
456
+
389
457
  const WhichGrid = isEditor ? WindowedGridEditor : Grid;
390
458
 
391
459
  let comboComponent = <Row {...refProps} justifyContent="center" alignItems="center" h={styles.FORM_COMBO_HEIGHT} flex={1} onLayout={() => setIsRendered(true)}>
460
+ {showXButton && !_.isNil(value) &&
461
+ <IconButton
462
+ _icon={{
463
+ as: Xmark,
464
+ color: 'trueGray.600',
465
+ size: 'sm',
466
+ }}
467
+ isDisabled={isDisabled}
468
+ onPress={onClearBtn}
469
+ h="100%"
470
+ bg={styles.FORM_COMBO_TRIGGER_BG}
471
+ _hover={{
472
+ bg: styles.FORM_COMBO_TRIGGER_HOVER_BG,
473
+ }}
474
+ />}
392
475
  {disableDirectEntry ?
393
476
  <Pressable
394
477
  onPress={toggleMenu}
@@ -424,17 +507,17 @@ export function ComboComponent(props) {
424
507
  _focus={{
425
508
  bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
426
509
  }}
427
- >{textValue}</Text>
510
+ >{textInputValue}</Text>
428
511
  </Pressable> :
429
512
  <Input
430
513
  ref={inputRef}
431
- value={textValue}
514
+ value={textInputValue}
432
515
  autoSubmit={true}
433
516
  isDisabled={isDisabled}
434
517
  onChangeValue={onInputChangeText}
435
518
  onKeyPress={onInputKeyPress}
519
+ onFocus={onInputFocus}
436
520
  onBlur={onInputBlur}
437
- onClick={onInputClick}
438
521
  onLayout={(e) => {
439
522
  // On web, this is not needed, but on RN it might be, so leave it in for now
440
523
  const {
@@ -447,15 +530,6 @@ export function ComboComponent(props) {
447
530
  setTop(top + height);
448
531
  setLeft(left);
449
532
  }}
450
- // onFocus={(e) => {
451
- // if (isBlocked.current) {
452
- // return;
453
- // }
454
- // if (!isRendered) {
455
- // return;
456
- // }
457
- // showMenu();
458
- // }}
459
533
  flex={1}
460
534
  h="100%"
461
535
  m={0}
@@ -535,20 +609,90 @@ export function ComboComponent(props) {
535
609
  };
536
610
  }}
537
611
  autoAdjustPageSizeToHeight={false}
538
- {...props}
612
+ {...gridProps}
613
+ reference="dropdownGrid"
614
+ parent={self}
539
615
  h={styles.FORM_COMBO_MENU_HEIGHT + 'px'}
616
+ newEntityDisplayValue={newEntityDisplayValue}
540
617
  disablePresetButtons={!isEditor}
541
- setSelection={(selection) => {
542
- // Decorator fn to add local functionality
543
- // Close the menu when row is selected on grid
544
- setSelection(selection);
545
- if (hideMenuOnSelection) {
618
+ onChangeSelection={(selection) => {
619
+
620
+ if (Repository && selection[0]?.isPhantom) {
621
+ // do nothing
622
+ return;
623
+ }
624
+
625
+ setGridSelection(selection);
626
+
627
+ if (Repository) {
628
+
629
+ // When we first open the menu, we try to match the selection to the value, ignore this
630
+ if (selection[0]?.displayValue === getDisplayValue()) {
631
+ return;
632
+ }
633
+
634
+ // when user selected the record matching the current value, kill search mode
635
+ if (selection[0]?.id === value) {
636
+ setIsSearchMode(false);
637
+ resetInputTextValue();
638
+ if (hideMenuOnSelection) {
639
+ hideMenu();
640
+ }
641
+ return;
642
+ }
643
+
644
+ setValue(selection[0] ? selection[0].id : null);
645
+
646
+ } else {
647
+
648
+ // When we first open the menu, we try to match the selection to the value, ignore this
649
+ if (selection[0] && selection[0][displayIx] === getDisplayValue()) {
650
+ return;
651
+ }
652
+
653
+ // when user selected the record matching the current value, kill search mode
654
+ if (selection[0] && selection[0][idIx] === value) {
655
+ setIsSearchMode(false);
656
+ resetInputTextValue();
657
+ if (hideMenuOnSelection) {
658
+ hideMenu();
659
+ }
660
+ return;
661
+ }
662
+
663
+ setValue(selection[0] ? selection[0][idIx] : null);
664
+
665
+ }
666
+
667
+ if (_.isEmpty(selection)) {
668
+ return;
669
+ }
670
+
671
+ if (hideMenuOnSelection && !isEditor) {
546
672
  hideMenu();
547
673
  }
674
+
548
675
  }}
549
- selectionMode={selectionMode}
550
- setValue={(value) => {
551
- setValue(value);
676
+ onSave={(selection) => {
677
+ const entity = selection[0];
678
+ if (entity?.id !== value) {
679
+ // Either a phantom record was just solidified into a real record, or a new (non-phantom) record was added.
680
+ // Select it and set the value of the combo.
681
+ setGridSelection([entity]);
682
+ const id = entity.id;
683
+ setValue(id);
684
+ }
685
+ }}
686
+ onRowPress={(item, e) => {
687
+ if (onRowPress) {
688
+ onRowPress(item, e);
689
+ return;
690
+ }
691
+ const id = Repository ? item.id : item[idIx];
692
+ if (id === value) {
693
+ hideMenu();
694
+ onInputFocus();
695
+ }
552
696
  }}
553
697
  />
554
698
  </Popover.Body>
@@ -565,9 +709,9 @@ export function ComboComponent(props) {
565
709
  }
566
710
 
567
711
  export const Combo = withComponent(
568
- withData(
569
- withValue(
570
- withSelection(
712
+ withAlert(
713
+ withData(
714
+ withValue(
571
715
  ComboComponent
572
716
  )
573
717
  )