@onehat/ui 0.3.58 → 0.3.60
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.
- package/package.json +1 -1
- package/src/Components/Form/Field/Combo/Combo.js +398 -226
- package/src/Components/Form/Field/Tag/Tag.js +55 -46
- package/src/Components/Form/Field/Tag/ValueBox.js +45 -0
- package/src/Components/Form/Form.js +32 -12
- package/src/Components/Grid/Grid.js +63 -58
- package/src/Components/Grid/GridRow.js +5 -2
- package/src/Components/Grid/NoRecordsFound.js +2 -0
- package/src/Components/Hoc/withAlert.js +17 -2
- package/src/Components/Hoc/withFilters.js +3 -1
- package/src/Components/Hoc/withValue.js +8 -0
- package/src/Components/Icons/Images.js +14 -0
- package/src/Constants/Alert.js +1 -0
- package/src/Functions/delay.js +3 -0
- package/src/Functions/isVideo.js +18 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useEffect, useRef, } from 'react';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
Modal,
|
|
4
4
|
Popover,
|
|
5
5
|
Pressable,
|
|
6
6
|
Row,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
Tooltip,
|
|
9
9
|
} from 'native-base';
|
|
10
10
|
import {
|
|
11
|
+
UI_MODE_REACT_NATIVE,
|
|
11
12
|
UI_MODE_WEB,
|
|
12
13
|
} from '../../../../Constants/UiModes.js';
|
|
13
14
|
import UiGlobals from '../../../../UiGlobals.js';
|
|
@@ -20,6 +21,7 @@ import emptyFn from '../../../../Functions/emptyFn.js';
|
|
|
20
21
|
import { Grid, WindowedGridEditor } from '../../../Grid/Grid.js';
|
|
21
22
|
import IconButton from '../../../Buttons/IconButton.js';
|
|
22
23
|
import CaretDown from '../../../Icons/CaretDown.js';
|
|
24
|
+
import Xmark from '../../../Icons/Xmark.js';
|
|
23
25
|
import _ from 'lodash';
|
|
24
26
|
|
|
25
27
|
export function ComboComponent(props) {
|
|
@@ -31,6 +33,7 @@ export function ComboComponent(props) {
|
|
|
31
33
|
menuMinWidth = 150,
|
|
32
34
|
disableDirectEntry = false,
|
|
33
35
|
hideMenuOnSelection = true,
|
|
36
|
+
showXButton = false,
|
|
34
37
|
_input = {},
|
|
35
38
|
isEditor = false,
|
|
36
39
|
isDisabled = false,
|
|
@@ -58,7 +61,6 @@ export function ComboComponent(props) {
|
|
|
58
61
|
triggerRef = useRef(),
|
|
59
62
|
menuRef = useRef(),
|
|
60
63
|
displayValueRef = useRef(null),
|
|
61
|
-
savedSearch = useRef(null),
|
|
62
64
|
typingTimeout = useRef(),
|
|
63
65
|
[isMenuShown, setIsMenuShown] = useState(false),
|
|
64
66
|
[isRendered, setIsRendered] = useState(false),
|
|
@@ -115,12 +117,6 @@ export function ComboComponent(props) {
|
|
|
115
117
|
toggleMenu = () => {
|
|
116
118
|
setIsMenuShown(!isMenuShown);
|
|
117
119
|
},
|
|
118
|
-
getSavedSearch = () => {
|
|
119
|
-
return savedSearch.current;
|
|
120
|
-
},
|
|
121
|
-
setSavedSearch = (val) => {
|
|
122
|
-
savedSearch.current = val;
|
|
123
|
-
},
|
|
124
120
|
resetInputTextValue = () => {
|
|
125
121
|
setTextInputValue(getDisplayValue());
|
|
126
122
|
},
|
|
@@ -184,9 +180,7 @@ export function ComboComponent(props) {
|
|
|
184
180
|
}
|
|
185
181
|
|
|
186
182
|
if (_.isEmpty(value)) {
|
|
187
|
-
|
|
188
|
-
hideMenu();
|
|
189
|
-
return;
|
|
183
|
+
setValue(null);
|
|
190
184
|
}
|
|
191
185
|
|
|
192
186
|
setTextInputValue(value);
|
|
@@ -198,7 +192,9 @@ export function ComboComponent(props) {
|
|
|
198
192
|
}, 300);
|
|
199
193
|
},
|
|
200
194
|
onInputFocus = (e) => {
|
|
201
|
-
inputRef.current.select
|
|
195
|
+
if (inputRef.current.select) {
|
|
196
|
+
inputRef.current.select();
|
|
197
|
+
}
|
|
202
198
|
},
|
|
203
199
|
onInputBlur = (e) => {
|
|
204
200
|
if (isEventStillInComponent(e)) {
|
|
@@ -231,6 +227,10 @@ export function ComboComponent(props) {
|
|
|
231
227
|
resetInputTextValue();
|
|
232
228
|
hideMenu();
|
|
233
229
|
},
|
|
230
|
+
onClearBtn = () => {
|
|
231
|
+
setTextInputValue('');
|
|
232
|
+
setValue(null);
|
|
233
|
+
}
|
|
234
234
|
isEventStillInComponent = (e) => {
|
|
235
235
|
const {
|
|
236
236
|
relatedTarget
|
|
@@ -272,11 +272,9 @@ export function ComboComponent(props) {
|
|
|
272
272
|
} else {
|
|
273
273
|
throw Error('Not yet implemented');
|
|
274
274
|
}
|
|
275
|
-
|
|
276
|
-
setSavedSearch(null);
|
|
277
275
|
|
|
278
276
|
} else {
|
|
279
|
-
throw Error('Not yet implemented');
|
|
277
|
+
// throw Error('Not yet implemented');
|
|
280
278
|
}
|
|
281
279
|
},
|
|
282
280
|
searchForMatches = async (value) => {
|
|
@@ -325,11 +323,11 @@ export function ComboComponent(props) {
|
|
|
325
323
|
Repository.filter(filter);
|
|
326
324
|
}
|
|
327
325
|
|
|
328
|
-
setSavedSearch(value);
|
|
329
326
|
setNewEntityDisplayValue(value); // capture the search query so we can tell Grid what to use for a new entity's displayValue
|
|
330
327
|
|
|
331
328
|
} else {
|
|
332
|
-
|
|
329
|
+
|
|
330
|
+
throw Error('Not yet implemented'); // NOTE: When implementing this, also implement clearGridFilters
|
|
333
331
|
|
|
334
332
|
// Search through data
|
|
335
333
|
found = _.find(data, (item) => {
|
|
@@ -390,7 +388,7 @@ export function ComboComponent(props) {
|
|
|
390
388
|
}
|
|
391
389
|
displayValue = entity?.displayValue || '';
|
|
392
390
|
} else {
|
|
393
|
-
const item = _.find(data, (datum) => datum[idIx] ===
|
|
391
|
+
const item = _.find(data, (datum) => datum[idIx] === value);
|
|
394
392
|
displayValue = (item && item[displayIx]) || '';
|
|
395
393
|
}
|
|
396
394
|
}
|
|
@@ -424,90 +422,51 @@ export function ComboComponent(props) {
|
|
|
424
422
|
return null;
|
|
425
423
|
}
|
|
426
424
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
refProps.ref = tooltipRef;
|
|
425
|
+
if (self) {
|
|
426
|
+
self.clear = onClearBtn;
|
|
430
427
|
}
|
|
431
428
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
'idIx',
|
|
438
|
-
'displayIx',
|
|
439
|
-
'value',
|
|
440
|
-
'disableView',
|
|
441
|
-
'disableCopy',
|
|
442
|
-
'disableDuplicate',
|
|
443
|
-
'disablePrint',
|
|
444
|
-
]);
|
|
445
|
-
|
|
446
|
-
const WhichGrid = isEditor ? WindowedGridEditor : Grid;
|
|
429
|
+
let xButton = null,
|
|
430
|
+
inputAndTrigger = null,
|
|
431
|
+
grid = null,
|
|
432
|
+
dropdownMenu = null,
|
|
433
|
+
assembledComponents = null;
|
|
447
434
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
p={2}
|
|
475
|
-
borderWidth={1}
|
|
476
|
-
borderColor="trueGray.400"
|
|
477
|
-
borderTopRightRadius={0}
|
|
478
|
-
borderBottomRightRadius={0}
|
|
479
|
-
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
480
|
-
bg={styles.FORM_COMBO_INPUT_BG}
|
|
481
|
-
_focus={{
|
|
482
|
-
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
483
|
-
}}
|
|
484
|
-
>{textInputValue}</Text>
|
|
485
|
-
</Pressable> :
|
|
486
|
-
<Input
|
|
435
|
+
if (showXButton && !_.isNil(value)) {
|
|
436
|
+
xButton = <IconButton
|
|
437
|
+
_icon={{
|
|
438
|
+
as: Xmark,
|
|
439
|
+
color: 'trueGray.600',
|
|
440
|
+
size: 'sm',
|
|
441
|
+
}}
|
|
442
|
+
isDisabled={isDisabled}
|
|
443
|
+
onPress={onClearBtn}
|
|
444
|
+
h="100%"
|
|
445
|
+
bg={styles.FORM_COMBO_TRIGGER_BG}
|
|
446
|
+
_hover={{
|
|
447
|
+
bg: styles.FORM_COMBO_TRIGGER_HOVER_BG,
|
|
448
|
+
}}
|
|
449
|
+
/>;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
if (UiGlobals.mode === UI_MODE_WEB) {
|
|
453
|
+
inputAndTrigger = <>
|
|
454
|
+
{disableDirectEntry ?
|
|
455
|
+
<Pressable
|
|
456
|
+
onPress={toggleMenu}
|
|
457
|
+
flex={1}
|
|
458
|
+
h="100%"
|
|
459
|
+
>
|
|
460
|
+
<Text
|
|
487
461
|
ref={inputRef}
|
|
488
|
-
value={textInputValue}
|
|
489
|
-
autoSubmit={true}
|
|
490
|
-
isDisabled={isDisabled}
|
|
491
|
-
onChangeValue={onInputChangeText}
|
|
492
|
-
onKeyPress={onInputKeyPress}
|
|
493
|
-
onFocus={onInputFocus}
|
|
494
|
-
onBlur={onInputBlur}
|
|
495
|
-
onLayout={(e) => {
|
|
496
|
-
// On web, this is not needed, but on RN it might be, so leave it in for now
|
|
497
|
-
const {
|
|
498
|
-
height,
|
|
499
|
-
width,
|
|
500
|
-
top,
|
|
501
|
-
left,
|
|
502
|
-
} = e.nativeEvent.layout;
|
|
503
|
-
setWidth(width);
|
|
504
|
-
setTop(top + height);
|
|
505
|
-
setLeft(left);
|
|
506
|
-
}}
|
|
507
462
|
flex={1}
|
|
508
463
|
h="100%"
|
|
464
|
+
numberOfLines={1}
|
|
465
|
+
ellipsizeMode="head"
|
|
509
466
|
m={0}
|
|
510
|
-
|
|
467
|
+
p={2}
|
|
468
|
+
borderWidth={1}
|
|
469
|
+
borderColor="trueGray.400"
|
|
511
470
|
borderTopRightRadius={0}
|
|
512
471
|
borderBottomRightRadius={0}
|
|
513
472
|
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
@@ -515,147 +474,360 @@ export function ComboComponent(props) {
|
|
|
515
474
|
_focus={{
|
|
516
475
|
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
517
476
|
}}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
<
|
|
521
|
-
ref={
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
color: 'primary.800',
|
|
525
|
-
size: 'sm',
|
|
526
|
-
}}
|
|
477
|
+
>{textInputValue}</Text>
|
|
478
|
+
</Pressable> :
|
|
479
|
+
<Input
|
|
480
|
+
ref={inputRef}
|
|
481
|
+
value={textInputValue}
|
|
482
|
+
autoSubmit={true}
|
|
527
483
|
isDisabled={isDisabled}
|
|
528
|
-
|
|
529
|
-
|
|
484
|
+
onChangeValue={onInputChangeText}
|
|
485
|
+
onKeyPress={onInputKeyPress}
|
|
486
|
+
onFocus={onInputFocus}
|
|
487
|
+
onBlur={onInputBlur}
|
|
488
|
+
onLayout={(e) => {
|
|
489
|
+
const {
|
|
490
|
+
height,
|
|
491
|
+
width,
|
|
492
|
+
} = e.nativeEvent.layout;
|
|
493
|
+
setWidth(Math.round(width));
|
|
494
|
+
setTop(Math.round(height));
|
|
495
|
+
}}
|
|
496
|
+
flex={1}
|
|
530
497
|
h="100%"
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
bg={styles.
|
|
537
|
-
|
|
538
|
-
bg: styles.
|
|
498
|
+
m={0}
|
|
499
|
+
autoSubmitDelay={0}
|
|
500
|
+
borderTopRightRadius={0}
|
|
501
|
+
borderBottomRightRadius={0}
|
|
502
|
+
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
503
|
+
bg={styles.FORM_COMBO_INPUT_BG}
|
|
504
|
+
_focus={{
|
|
505
|
+
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
539
506
|
}}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
507
|
+
{..._input}
|
|
508
|
+
/>}
|
|
509
|
+
<IconButton
|
|
510
|
+
ref={triggerRef}
|
|
511
|
+
_icon={{
|
|
512
|
+
as: CaretDown,
|
|
513
|
+
color: 'primary.800',
|
|
514
|
+
size: 'sm',
|
|
515
|
+
}}
|
|
516
|
+
isDisabled={isDisabled}
|
|
517
|
+
onPress={onTriggerPress}
|
|
518
|
+
onBlur={onTriggerBlur}
|
|
519
|
+
h="100%"
|
|
520
|
+
borderWidth={1}
|
|
521
|
+
borderColor="#bbb"
|
|
522
|
+
borderLeftWidth={0}
|
|
523
|
+
borderLeftRadius={0}
|
|
524
|
+
borderRightRadius="md"
|
|
525
|
+
bg={styles.FORM_COMBO_TRIGGER_BG}
|
|
526
|
+
_hover={{
|
|
527
|
+
bg: styles.FORM_COMBO_TRIGGER_HOVER_BG,
|
|
528
|
+
}}
|
|
529
|
+
/>
|
|
530
|
+
</>;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (UiGlobals.mode === UI_MODE_REACT_NATIVE) {
|
|
534
|
+
// This input and trigger are for show
|
|
535
|
+
// The just show the current value and open the menu
|
|
536
|
+
inputAndTrigger = <>
|
|
537
|
+
<Pressable
|
|
538
|
+
onPress={showMenu}
|
|
539
|
+
flex={1}
|
|
540
|
+
>
|
|
541
|
+
<Text
|
|
542
|
+
flex={1}
|
|
543
|
+
h="100%"
|
|
544
|
+
numberOfLines={1}
|
|
545
|
+
ellipsizeMode="head"
|
|
546
|
+
m={0}
|
|
547
|
+
p={2}
|
|
548
|
+
borderWidth={1}
|
|
549
|
+
borderColor="trueGray.400"
|
|
550
|
+
borderTopRightRadius={0}
|
|
551
|
+
borderBottomRightRadius={0}
|
|
552
|
+
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
553
|
+
bg={styles.FORM_COMBO_INPUT_BG}
|
|
554
|
+
_focus={{
|
|
555
|
+
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
546
556
|
}}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
557
|
+
>{textInputValue}</Text>
|
|
558
|
+
</Pressable>
|
|
559
|
+
<IconButton
|
|
560
|
+
ref={triggerRef}
|
|
561
|
+
_icon={{
|
|
562
|
+
as: CaretDown,
|
|
563
|
+
color: 'primary.800',
|
|
564
|
+
size: 'sm',
|
|
565
|
+
}}
|
|
566
|
+
isDisabled={isDisabled}
|
|
567
|
+
onPress={onTriggerPress}
|
|
568
|
+
h="100%"
|
|
569
|
+
borderWidth={1}
|
|
570
|
+
borderColor="#bbb"
|
|
571
|
+
borderLeftWidth={0}
|
|
572
|
+
borderLeftRadius={0}
|
|
573
|
+
borderRightRadius="md"
|
|
574
|
+
bg={styles.FORM_COMBO_TRIGGER_BG}
|
|
575
|
+
_hover={{
|
|
576
|
+
bg: styles.FORM_COMBO_TRIGGER_HOVER_BG,
|
|
577
|
+
}}
|
|
578
|
+
/>
|
|
579
|
+
</>;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
if (isMenuShown) {
|
|
583
|
+
const gridProps = _.pick(props, [
|
|
584
|
+
'Editor',
|
|
585
|
+
'model',
|
|
586
|
+
'Repository',
|
|
587
|
+
'data',
|
|
588
|
+
'idIx',
|
|
589
|
+
'displayIx',
|
|
590
|
+
'value',
|
|
591
|
+
'disableView',
|
|
592
|
+
'disableCopy',
|
|
593
|
+
'disableDuplicate',
|
|
594
|
+
'disablePrint',
|
|
595
|
+
]);
|
|
596
|
+
const WhichGrid = isEditor ? WindowedGridEditor : Grid;
|
|
597
|
+
grid = <WhichGrid
|
|
598
|
+
showHeaders={false}
|
|
599
|
+
showHovers={true}
|
|
600
|
+
shadow={1}
|
|
601
|
+
getRowProps={() => {
|
|
602
|
+
return {
|
|
603
|
+
borderBottomWidth: 1,
|
|
604
|
+
borderBottomColor: 'trueGray.300',
|
|
605
|
+
py: 1,
|
|
606
|
+
pl: 4,
|
|
607
|
+
pr: 2,
|
|
608
|
+
w: '100%',
|
|
609
|
+
};
|
|
610
|
+
}}
|
|
611
|
+
autoAdjustPageSizeToHeight={false}
|
|
612
|
+
{...gridProps}
|
|
613
|
+
reference="dropdownGrid"
|
|
614
|
+
parent={self}
|
|
615
|
+
h={UiGlobals.mode === UI_MODE_WEB ? styles.FORM_COMBO_MENU_HEIGHT + 'px' : null}
|
|
616
|
+
newEntityDisplayValue={newEntityDisplayValue}
|
|
617
|
+
disablePresetButtons={!isEditor}
|
|
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) {
|
|
672
|
+
hideMenu();
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
}}
|
|
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
|
+
}
|
|
696
|
+
}}
|
|
697
|
+
/>;
|
|
698
|
+
if (UiGlobals.mode === UI_MODE_WEB) {
|
|
699
|
+
dropdownMenu = <Popover
|
|
700
|
+
isOpen={isMenuShown}
|
|
701
|
+
onClose={() => {
|
|
702
|
+
hideMenu();
|
|
703
|
+
}}
|
|
704
|
+
trigger={emptyFn}
|
|
705
|
+
trapFocus={false}
|
|
706
|
+
placement={'auto'}
|
|
707
|
+
// _fade={{
|
|
708
|
+
// entryDuration: 0, // Doesn't work, as Popover doesn't have animation controls like Modal does. See node_modules/native-base/src/components/composites/Popover/Popover.tsx line 99 (vs .../composites/Modal/Modal.tsx line 113 which has ..._fade) I added a feature request to NativeBase https://github.com/GeekyAnts/NativeBase/issues/5651
|
|
709
|
+
// }}
|
|
710
|
+
{...props}
|
|
711
|
+
>
|
|
712
|
+
<Popover.Content
|
|
713
|
+
position="absolute"
|
|
714
|
+
top={top + 'px'}
|
|
715
|
+
left={left + 'px'}
|
|
716
|
+
w={width + 'px'}
|
|
717
|
+
minWidth={menuMinWidth}
|
|
718
|
+
overflow="auto"
|
|
719
|
+
bg="#fff"
|
|
720
|
+
|
|
721
|
+
h={200}
|
|
554
722
|
>
|
|
555
|
-
<Popover.
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
overflow="auto"
|
|
562
|
-
bg="#fff"
|
|
723
|
+
<Popover.Body
|
|
724
|
+
ref={menuRef}
|
|
725
|
+
borderWidth={1}
|
|
726
|
+
borderColor='trueGray.400'
|
|
727
|
+
borderTopWidth={0}
|
|
728
|
+
p={0}
|
|
563
729
|
>
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
730
|
+
{grid}
|
|
731
|
+
</Popover.Body>
|
|
732
|
+
</Popover.Content>
|
|
733
|
+
</Popover>;
|
|
734
|
+
}
|
|
735
|
+
if (UiGlobals.mode === UI_MODE_REACT_NATIVE) {
|
|
736
|
+
const inputAndTriggerClone = // for RN, this is the actual input and trigger, as we need them to appear up above in the modal
|
|
737
|
+
<Row h={10}>
|
|
738
|
+
{disableDirectEntry ?
|
|
739
|
+
<Text
|
|
740
|
+
ref={inputRef}
|
|
741
|
+
flex={1}
|
|
742
|
+
h="100%"
|
|
743
|
+
numberOfLines={1}
|
|
744
|
+
ellipsizeMode="head"
|
|
745
|
+
m={0}
|
|
746
|
+
p={2}
|
|
747
|
+
borderWidth={1}
|
|
748
|
+
borderColor="trueGray.400"
|
|
749
|
+
borderTopRightRadius={0}
|
|
750
|
+
borderBottomRightRadius={0}
|
|
751
|
+
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
752
|
+
bg={styles.FORM_COMBO_INPUT_BG}
|
|
753
|
+
_focus={{
|
|
754
|
+
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
755
|
+
}}
|
|
756
|
+
>{textInputValue}</Text> :
|
|
757
|
+
<Input
|
|
758
|
+
ref={inputRef}
|
|
759
|
+
value={textInputValue}
|
|
760
|
+
autoSubmit={true}
|
|
761
|
+
isDisabled={isDisabled}
|
|
762
|
+
onChangeValue={onInputChangeText}
|
|
763
|
+
onKeyPress={onInputKeyPress}
|
|
764
|
+
onFocus={onInputFocus}
|
|
765
|
+
onBlur={onInputBlur}
|
|
766
|
+
flex={1}
|
|
767
|
+
h="100%"
|
|
768
|
+
m={0}
|
|
769
|
+
autoSubmitDelay={0}
|
|
770
|
+
borderTopRightRadius={0}
|
|
771
|
+
borderBottomRightRadius={0}
|
|
772
|
+
fontSize={styles.FORM_COMBO_INPUT_FONTSIZE}
|
|
773
|
+
bg={styles.FORM_COMBO_INPUT_BG}
|
|
774
|
+
_focus={{
|
|
775
|
+
bg: styles.FORM_COMBO_INPUT_FOCUS_BG,
|
|
776
|
+
}}
|
|
777
|
+
{..._input}
|
|
778
|
+
/>}
|
|
779
|
+
<IconButton
|
|
780
|
+
_icon={{
|
|
781
|
+
as: CaretDown,
|
|
782
|
+
color: 'primary.800',
|
|
783
|
+
size: 'sm',
|
|
784
|
+
}}
|
|
785
|
+
isDisabled={isDisabled}
|
|
786
|
+
onPress={() => hideMenu()}
|
|
787
|
+
h="100%"
|
|
788
|
+
borderWidth={1}
|
|
789
|
+
borderColor="#bbb"
|
|
790
|
+
borderLeftWidth={0}
|
|
791
|
+
borderLeftRadius={0}
|
|
792
|
+
borderRightRadius="md"
|
|
793
|
+
bg={styles.FORM_COMBO_TRIGGER_BG}
|
|
794
|
+
_hover={{
|
|
795
|
+
bg: styles.FORM_COMBO_TRIGGER_HOVER_BG,
|
|
796
|
+
}}
|
|
797
|
+
/>
|
|
798
|
+
</Row>;
|
|
799
|
+
dropdownMenu = <Modal
|
|
800
|
+
isOpen={true}
|
|
801
|
+
onClose={() => setIsMenuShown(false)}
|
|
802
|
+
top="30%"
|
|
803
|
+
w="100%"
|
|
804
|
+
h={400}
|
|
805
|
+
px={5}
|
|
806
|
+
>
|
|
807
|
+
{inputAndTriggerClone}
|
|
808
|
+
{grid}
|
|
809
|
+
</Modal>;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
const refProps = {};
|
|
814
|
+
if (tooltipRef) {
|
|
815
|
+
refProps.ref = tooltipRef;
|
|
816
|
+
}
|
|
817
|
+
assembledComponents = <Row {...refProps} justifyContent="center" alignItems="center" h={styles.FORM_COMBO_HEIGHT} flex={1} onLayout={() => setIsRendered(true)}>
|
|
818
|
+
{xButton}
|
|
819
|
+
{inputAndTrigger}
|
|
820
|
+
{additionalButtons}
|
|
821
|
+
{dropdownMenu}
|
|
822
|
+
</Row>;
|
|
823
|
+
|
|
652
824
|
if (tooltip) {
|
|
653
|
-
|
|
654
|
-
{
|
|
825
|
+
assembledComponents = <Tooltip label={tooltip} placement={tooltipPlacement}>
|
|
826
|
+
{assembledComponents}
|
|
655
827
|
</Tooltip>;
|
|
656
828
|
}
|
|
657
829
|
|
|
658
|
-
return
|
|
830
|
+
return assembledComponents;
|
|
659
831
|
}
|
|
660
832
|
|
|
661
833
|
export const Combo = withComponent(
|