@onehat/ui 0.4.39 → 0.4.41

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onehat/ui",
3
- "version": "0.4.39",
3
+ "version": "0.4.41",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -5,7 +5,6 @@ import {
5
5
  ButtonSpinner,
6
6
  ButtonIcon,
7
7
  ButtonGroup,
8
- Tooltip,
9
8
  } from '@project-components/Gluestack';
10
9
  import withComponent from '../Hoc/withComponent.js';
11
10
  import withTooltip from '../Hoc/withTooltip.js';
@@ -22,7 +21,6 @@ const ButtonComponent = forwardRef((props, ref) => {
22
21
  _icon, // props for icon
23
22
  _rightIcon, // props for rightIcon
24
23
  _text = {}, // props for ButtonText
25
- tooltip,
26
24
  ...propsToPass
27
25
  } = props;
28
26
 
@@ -61,17 +59,12 @@ const ButtonComponent = forwardRef((props, ref) => {
61
59
  className += ' ' + propsToPass.className;
62
60
  }
63
61
 
64
- let button = <Button {...propsToPass} className={className} ref={ref}>
65
- {isLoading && <ButtonSpinner className="ButtonSpinner" {..._spinner} />}
66
- {icon}
67
- {text && <ButtonText className="ButtonText" {..._text}>{text}</ButtonText>}
68
- {rightIcon}
69
- </Button>;
70
- if (tooltip) {
71
- button = <Tooltip text={tooltip}>{button}</Tooltip>;
72
- }
73
- return button;
74
-
62
+ return <Button {...propsToPass} className={className} ref={ref}>
63
+ {isLoading && <ButtonSpinner className="ButtonSpinner" {..._spinner} />}
64
+ {icon}
65
+ {text && <ButtonText className="ButtonText" {..._text}>{text}</ButtonText>}
66
+ {rightIcon}
67
+ </Button>;
75
68
  });
76
69
 
77
70
  export default withComponent(withTooltip(ButtonComponent));
@@ -6,7 +6,6 @@ import {
6
6
  } from '@project-components/Gluestack';
7
7
  import Date from '../Form/Field/Date.js';
8
8
  import testProps from '../../Functions/testProps.js';
9
- import withTooltip from '../Hoc/withTooltip.js';
10
9
  import withValue from '../Hoc/withValue.js';
11
10
  import _ from 'lodash';
12
11
 
@@ -22,6 +21,7 @@ const
22
21
  minValue,
23
22
  maxValue,
24
23
  tooltip,
24
+ tooltipPlacement,
25
25
 
26
26
  // withComponent
27
27
  self,
@@ -100,6 +100,7 @@ const
100
100
  minValue={minValue}
101
101
  maxValue={maxValue}
102
102
  tooltip={(tooltip ? tooltip + ' ' : '') + 'Low'}
103
+ tooltipPlacement={tooltipPlacement}
103
104
  limitWidth={true}
104
105
  parent={self}
105
106
  reference="low"
@@ -113,6 +114,7 @@ const
113
114
  minValue={minValue}
114
115
  maxValue={maxValue}
115
116
  tooltip={(tooltip ? tooltip + ' ' : '') + 'High'}
117
+ tooltipPlacement={tooltipPlacement}
116
118
  limitWidth={true}
117
119
  parent={self}
118
120
  reference="high"
@@ -17,7 +17,8 @@ const
17
17
  high: null,
18
18
  },
19
19
  setValue,
20
- tooltip = '',
20
+ tooltip,
21
+ tooltipPlacement,
21
22
 
22
23
  minValue = 0,
23
24
  maxValue,
@@ -82,6 +83,7 @@ const
82
83
  minValue={minValue}
83
84
  maxValue={maxValue}
84
85
  tooltip={(tooltip ? tooltip + ' ' : '') + 'Low'}
86
+ tooltipPlacement={tooltipPlacement}
85
87
  className="max-w-[150px]"
86
88
  />
87
89
  <Text className="px-2 select-none">to</Text>
@@ -93,6 +95,7 @@ const
93
95
  minValue={minValue}
94
96
  maxValue={maxValue}
95
97
  tooltip={(tooltip ? tooltip + ' ' : '') + 'High'}
98
+ tooltipPlacement={tooltipPlacement}
96
99
  className="max-w-[150px]"
97
100
  />
98
101
  </HStack>;
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useRef, } from 'react';
1
+ import { forwardRef, useState, useEffect, useRef, } from 'react';
2
2
  import {
3
3
  Box,
4
4
  HStack,
@@ -9,7 +9,6 @@ import {
9
9
  Pressable,
10
10
  Text,
11
11
  TextNative,
12
- Tooltip,
13
12
  VStackNative,
14
13
  } from '@project-components/Gluestack';
15
14
  import {
@@ -37,13 +36,11 @@ import _ from 'lodash';
37
36
 
38
37
  const FILTER_NAME = 'q';
39
38
 
40
- export function ComboComponent(props) {
39
+ export const ComboComponent = forwardRef((props, ref) => {
41
40
 
42
41
  const {
43
42
  additionalButtons,
44
43
  autoFocus = false,
45
- tooltipRef = null,
46
- tooltip = null,
47
44
  menuMinWidth,
48
45
  disableDirectEntry = false,
49
46
  hideMenuOnSelection = true,
@@ -58,7 +55,6 @@ export function ComboComponent(props) {
58
55
  minimizeForRow = false,
59
56
  reloadOnTrigger = false,
60
57
  menuHeight,
61
- tooltipPlacement = 'bottom',
62
58
  placeholder,
63
59
  onRowPress,
64
60
  icon,
@@ -68,6 +64,8 @@ export function ComboComponent(props) {
68
64
  onGridDelete, // to hook into when menu deletes (ComboEditor only)
69
65
  onSubmit, // when Combo is used in a Tag, call this when the user submits the Combo value (i.e. presses Enter or clicks a row)
70
66
  newEntityDisplayProperty,
67
+ tooltip = null,
68
+ tooltipPlacement = 'bottom',
71
69
  testID,
72
70
 
73
71
  // withComponent
@@ -630,6 +628,14 @@ export function ComboComponent(props) {
630
628
  InputLeftElement={inputIconElement}
631
629
  autoSubmitDelay={500}
632
630
  placeholder={placeholder}
631
+ tooltip={tooltip}
632
+ tooltipPlacement={tooltipPlacement}
633
+ tooltipClassName={`
634
+ grow
635
+ h-auto
636
+ self-stretch
637
+ flex-1
638
+ `}
633
639
  className={`
634
640
  Combo-Input
635
641
  grow
@@ -858,6 +864,13 @@ export function ComboComponent(props) {
858
864
  InputLeftElement={inputIconElement}
859
865
  autoSubmitDelay={500}
860
866
  placeholder={placeholder}
867
+ tooltip={tooltip}
868
+ tooltipPlacement={tooltipPlacement}
869
+ tooltipClassName={`
870
+ grow
871
+ h-full
872
+ flex-1
873
+ `}
861
874
  className={`
862
875
  Combo-inputClone-Input
863
876
  grow
@@ -964,6 +977,12 @@ export function ComboComponent(props) {
964
977
  InputLeftElement={inputIconElement}
965
978
  autoSubmitDelay={500}
966
979
  placeholder={placeholder}
980
+ tooltip={tooltip}
981
+ tooltipPlacement={tooltipPlacement}
982
+ tooltipClassName={`
983
+ h-full
984
+ flex-1
985
+ `}
967
986
  className={`
968
987
  h-full
969
988
  flex-1
@@ -1014,10 +1033,6 @@ export function ComboComponent(props) {
1014
1033
  </Modal>;
1015
1034
  }
1016
1035
  }
1017
- const refProps = {};
1018
- if (tooltipRef) {
1019
- refProps.ref = tooltipRef;
1020
- }
1021
1036
 
1022
1037
  let className = `
1023
1038
  Combo-HStack
@@ -1043,7 +1058,6 @@ export function ComboComponent(props) {
1043
1058
  className="Combo-VStack"
1044
1059
  >
1045
1060
  <HStack
1046
- {...refProps}
1047
1061
  className={className}
1048
1062
  >
1049
1063
  {xButton}
@@ -1059,7 +1073,6 @@ export function ComboComponent(props) {
1059
1073
  } else {
1060
1074
  assembledComponents =
1061
1075
  <HStackNative
1062
- {...refProps}
1063
1076
  testID={testID}
1064
1077
  onLayout={onLayout}
1065
1078
  className={className}
@@ -1115,15 +1128,9 @@ export function ComboComponent(props) {
1115
1128
  </>;
1116
1129
  }
1117
1130
 
1118
- if (tooltip) {
1119
- // TODO: implement withTooltip for Combo
1120
- // assembledComponents = <Tooltip label={tooltip} placement={tooltipPlacement} className="h-full">
1121
- // {assembledComponents}
1122
- // </Tooltip>;
1123
- }
1124
-
1125
1131
  return assembledComponents;
1126
- }
1132
+
1133
+ });
1127
1134
 
1128
1135
  export const Combo = withComponent(
1129
1136
  withAlert(
@@ -12,8 +12,8 @@ import {
12
12
  } from '../../../../Constants/MeterTypes.js';
13
13
 
14
14
  const data = [
15
- [METER_TYPES__HOURS, 'Hours'],
16
- [METER_TYPES__MILES, 'Miles'],
15
+ [METER_TYPES__HOURS, 'Time (hrs)'],
16
+ [METER_TYPES__MILES, 'Distance (mi/km)'],
17
17
  ];
18
18
  function MeterTypesCombo(props) {
19
19
  return <ArrayCombo
@@ -24,6 +24,7 @@ export default function PageSizeCombo(props) {
24
24
  value={pageSize}
25
25
  onChangeValue={(value) => Repository.setPageSize(value)}
26
26
  tooltip="Page Size"
27
+ tooltipClassName="w-[100px]"
27
28
  allowNull={false}
28
29
  disableDirectEntry={true}
29
30
  />
@@ -24,7 +24,6 @@ import Input from '../Field/Input.js';
24
24
  import IconButton from '../../Buttons/IconButton.js';
25
25
  import Xmark from '../../Icons/Xmark.js';
26
26
  import withComponent from '../../Hoc/withComponent.js';
27
- import withTooltip from '../../Hoc/withTooltip.js';
28
27
  import withValue from '../../Hoc/withValue.js';
29
28
  import emptyFn from '../../../Functions/emptyFn.js';
30
29
  import testProps from '../../../Functions/testProps.js';
@@ -51,6 +50,8 @@ export const DateElement = forwardRef((props, ref) => {
51
50
  minimizeForRow = false,
52
51
  minValue,
53
52
  maxValue,
53
+ tooltip = null,
54
+ tooltipPlacement = 'bottom',
54
55
  testID,
55
56
 
56
57
  // withComponent
@@ -359,6 +360,12 @@ export const DateElement = forwardRef((props, ref) => {
359
360
  onFocus={onInputFocus}
360
361
  autoSubmit={true}
361
362
  isDisabled={isDisabled}
363
+ tooltip={tooltip}
364
+ tooltipPlacement={tooltipPlacement}
365
+ tooltipClassName={`
366
+ flex-1
367
+ h-full
368
+ `}
362
369
  // onLayout={(e) => {
363
370
  // const {
364
371
  // height,
@@ -510,6 +517,12 @@ export const DateElement = forwardRef((props, ref) => {
510
517
  onBlur={onInputBlur}
511
518
  autoSubmitDelay={1000}
512
519
  placeholder={placeholder}
520
+ tooltip={tooltip}
521
+ tooltipPlacement={tooltipPlacement}
522
+ tooltipClassName={`
523
+ flex-1
524
+ h-full
525
+ `}
513
526
  className={`
514
527
  flex-1
515
528
  h-full
@@ -602,4 +615,4 @@ export const DateElement = forwardRef((props, ref) => {
602
615
 
603
616
  });
604
617
 
605
- export default withComponent(withValue(withTooltip(DateElement)));
618
+ export default withComponent(withValue(DateElement));
@@ -9,14 +9,11 @@ import IconButton from '../../Buttons/IconButton.js';
9
9
  import Input from './Input.js';
10
10
  import testProps from '../../../Functions/testProps.js';
11
11
  import withComponent from '../../Hoc/withComponent.js';
12
- import withTooltip from '../../Hoc/withTooltip.js';
13
12
  import withValue from '../../Hoc/withValue.js';
14
13
  import Plus from '../../Icons/Plus.js';
15
14
  import Minus from '../../Icons/Minus.js';
16
15
  import _ from 'lodash';
17
16
 
18
- const InputWithTooltip = withTooltip(Input);
19
-
20
17
  function NumberElement(props) {
21
18
  let {
22
19
  value,
@@ -24,7 +21,8 @@ function NumberElement(props) {
24
21
  minValue,
25
22
  maxValue,
26
23
  autoSubmitDelay = UiGlobals.autoSubmitDelay,
27
- tooltip = null,
24
+ tooltip,
25
+ tooltipPlacement,
28
26
  isDisabled = false,
29
27
  testID,
30
28
  } = props,
@@ -158,15 +156,15 @@ function NumberElement(props) {
158
156
  width: 40,
159
157
  }}
160
158
  />
161
- <InputWithTooltip
159
+ <Input
162
160
  testID={testID}
163
161
  value={inputValue}
164
162
  onChangeText={onChangeText}
165
163
  onKeyPress={onInputKeyPress}
166
164
  isDisabled={isDisabled}
167
165
  tooltip={tooltip}
166
+ tooltipPlacement={tooltipPlacement}
168
167
  className={`
169
- InputWithTooltip
170
168
  h-full
171
169
  text-center
172
170
  rounded-none
@@ -24,6 +24,7 @@ export default function PageSizeSelect(props) {
24
24
  value={pageSize}
25
25
  onChangeValue={(value) => Repository.setPageSize(value)}
26
26
  tooltip="Page Size"
27
+ tooltipClassName="w-[70px]"
27
28
  />
28
29
  </HStack>;
29
30
  }, [
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useRef, } from 'react';
1
+ import { useState, useEffect, useRef, } from 'react';
2
2
  import {
3
3
  HStack,
4
4
  Text,
@@ -13,211 +13,206 @@ import Slider from '@react-native-community/slider'; // https://www.npmjs.com/pa
13
13
  import UiGlobals from '../../../UiGlobals.js';
14
14
  import testProps from '../../../Functions/testProps.js';
15
15
  import withComponent from '../../Hoc/withComponent.js';
16
- import withTooltip from '../../Hoc/withTooltip.js';
17
16
  import withValue from '../../Hoc/withValue.js';
18
17
  import _ from 'lodash';
19
18
 
20
19
  const FAKE_ZERO = 0.0000000001; // Slider doesn't like zero
21
20
 
22
- const InputWithTooltip = withTooltip(Input);
23
-
24
- const
25
- SliderElement = (props) => {
26
- let {
27
- value = 0,
28
- setValue,
29
- minValue = 0,
30
- maxValue = 100,
31
- step = 10,
32
- autoSubmitDelay = UiGlobals.autoSubmitDelay,
33
- minimizeForRow = false,
34
- tooltip = null,
35
- isDisabled = false,
36
- testID,
37
- } = props,
38
- styles = UiGlobals.styles,
39
- debouncedSetValueRef = useRef(),
40
- [localValue, setLocalValue] = useState(value),
41
- onInputKeyPress = (e) => {
42
- const key = e.nativeEvent.key; // e.key works on web, but not mobile; so use e.nativeEvent.key which works on both
43
- switch(key) {
44
- case 'ArrowDown':
45
- onDecrement();
46
- break;
47
- case 'ArrowUp':
48
- onIncrement();
49
- break;
50
- case 'Enter':
51
- debouncedSetValueRef.current?.cancel();
52
- setValue(value);
53
- break;
54
- case 'ArrowLeft':
55
- case 'ArrowRight':
56
- case 'Tab':
57
- case 'Backspace':
58
- return;
59
- default:
60
- }
61
- if (!key.match(/^[\-\d\.]*$/)) {
62
- e.preventDefault(); // kill anything that's not a number
63
- }
64
- },
65
- onChangeText = (value) => {
66
- if (!value || value === '') {
67
- value = 0; // empty string makes value null
68
- } else if (value.match(/\.$/)) { // value ends with a decimal point
69
- // don't parseFloat, otherwise we'll lose the decimal point
70
- } else if (value.match(/0$/)) { // value ends with a zero
71
- // don't parseFloat, otherwise we'll lose the ability to do things like 1.03
72
- } else {
73
- value = parseFloat(value, 10);
74
- }
75
- if (value < minValue) {
76
- value = minValue;
77
- } else if (value > maxValue) {
78
- value = maxValue;
79
- }
80
- setLocalValue(value);
81
- debouncedSetValueRef.current(value);
82
- },
83
- onDecrement = () => {
84
- let localValue = value;
85
- if (minValue && localValue === minValue) {
86
- return;
87
- }
88
- if (!localValue) {
89
- localValue = 0;
90
- }
91
- localValue = new Decimal(localValue).minus(step).toNumber();
92
- if (minValue > localValue) {
93
- localValue = minValue;
94
- }
95
- setValue(localValue);
96
- },
97
- onIncrement = () => {
98
- let localValue = value;
99
- if (maxValue && localValue === maxValue) {
21
+ function SliderElement(props) {
22
+ let {
23
+ value = 0,
24
+ setValue,
25
+ minValue = 0,
26
+ maxValue = 100,
27
+ step = 10,
28
+ autoSubmitDelay = UiGlobals.autoSubmitDelay,
29
+ minimizeForRow = false,
30
+ tooltip,
31
+ tooltipPlacement,
32
+ isDisabled = false,
33
+ testID,
34
+ } = props,
35
+ styles = UiGlobals.styles,
36
+ debouncedSetValueRef = useRef(),
37
+ [localValue, setLocalValue] = useState(value),
38
+ onInputKeyPress = (e) => {
39
+ const key = e.nativeEvent.key; // e.key works on web, but not mobile; so use e.nativeEvent.key which works on both
40
+ switch(key) {
41
+ case 'ArrowDown':
42
+ onDecrement();
43
+ break;
44
+ case 'ArrowUp':
45
+ onIncrement();
46
+ break;
47
+ case 'Enter':
48
+ debouncedSetValueRef.current?.cancel();
49
+ setValue(value);
50
+ break;
51
+ case 'ArrowLeft':
52
+ case 'ArrowRight':
53
+ case 'Tab':
54
+ case 'Backspace':
100
55
  return;
101
- }
102
- if (!localValue) {
103
- localValue = 0;
104
- }
105
- localValue = new Decimal(localValue).plus(step).toNumber();
106
- if (maxValue < localValue) {
107
- localValue = maxValue;
108
- }
109
- setValue(localValue);
110
- };
111
-
112
- useEffect(() => {
113
- // Set up debounce fn
114
- // Have to do this because otherwise, lodash tries to create a debounced version of the fn from only this render
115
- debouncedSetValueRef.current?.cancel(); // Cancel any previous debounced fn
116
- debouncedSetValueRef.current = _.debounce(setValue, autoSubmitDelay);
117
- }, [setValue]);
118
-
119
- useEffect(() => {
120
-
121
- // Make local value conform to externally changed value
122
- if (value !== localValue) {
123
- setLocalValue(value);
56
+ default:
57
+ }
58
+ if (!key.match(/^[\-\d\.]*$/)) {
59
+ e.preventDefault(); // kill anything that's not a number
60
+ }
61
+ },
62
+ onChangeText = (value) => {
63
+ if (!value || value === '') {
64
+ value = 0; // empty string makes value null
65
+ } else if (value.match(/\.$/)) { // value ends with a decimal point
66
+ // don't parseFloat, otherwise we'll lose the decimal point
67
+ } else if (value.match(/0$/)) { // value ends with a zero
68
+ // don't parseFloat, otherwise we'll lose the ability to do things like 1.03
69
+ } else {
70
+ value = parseFloat(value, 10);
71
+ }
72
+ if (value < minValue) {
73
+ value = minValue;
74
+ } else if (value > maxValue) {
75
+ value = maxValue;
76
+ }
77
+ setLocalValue(value);
78
+ debouncedSetValueRef.current(value);
79
+ },
80
+ onDecrement = () => {
81
+ let localValue = value;
82
+ if (minValue && localValue === minValue) {
83
+ return;
84
+ }
85
+ if (!localValue) {
86
+ localValue = 0;
87
+ }
88
+ localValue = new Decimal(localValue).minus(step).toNumber();
89
+ if (minValue > localValue) {
90
+ localValue = minValue;
91
+ }
92
+ setValue(localValue);
93
+ },
94
+ onIncrement = () => {
95
+ let localValue = value;
96
+ if (maxValue && localValue === maxValue) {
97
+ return;
98
+ }
99
+ if (!localValue) {
100
+ localValue = 0;
124
101
  }
102
+ localValue = new Decimal(localValue).plus(step).toNumber();
103
+ if (maxValue < localValue) {
104
+ localValue = maxValue;
105
+ }
106
+ setValue(localValue);
107
+ };
125
108
 
126
- }, [value]);
109
+ useEffect(() => {
110
+ // Set up debounce fn
111
+ // Have to do this because otherwise, lodash tries to create a debounced version of the fn from only this render
112
+ debouncedSetValueRef.current?.cancel(); // Cancel any previous debounced fn
113
+ debouncedSetValueRef.current = _.debounce(setValue, autoSubmitDelay);
114
+ }, [setValue]);
127
115
 
128
- let sliderValue = value;
116
+ useEffect(() => {
129
117
 
130
- if (localValue === null || typeof localValue === 'undefined') {
131
- localValue = ''; // If the value is null or undefined, don't let this be an uncontrolled input
118
+ // Make local value conform to externally changed value
119
+ if (value !== localValue) {
120
+ setLocalValue(value);
132
121
  }
133
122
 
134
- if (sliderValue === null || typeof sliderValue === 'undefined') {
135
- sliderValue = 0; // If the value is null or undefined, force slider to use zero
136
- }
123
+ }, [value]);
137
124
 
138
- // convert localValue to string if necessary, because numbers work on web but not mobile; while strings work in both places
139
- let inputValue = localValue;
140
- if (_.isNumber(inputValue)) {
141
- inputValue = '' + inputValue;
142
- }
125
+ let sliderValue = value;
143
126
 
144
- const style = props.style || {};
145
- if (!hasWidth(props) && !hasFlex(props)) {
146
- style.flex = 1;
147
- }
127
+ if (localValue === null || typeof localValue === 'undefined') {
128
+ localValue = ''; // If the value is null or undefined, don't let this be an uncontrolled input
129
+ }
148
130
 
149
- if (sliderValue === 0) {
150
- sliderValue = FAKE_ZERO; // Slider doesn't like zero
151
- }
131
+ if (sliderValue === null || typeof sliderValue === 'undefined') {
132
+ sliderValue = 0; // If the value is null or undefined, force slider to use zero
133
+ }
152
134
 
153
- let className = `
154
- w-full
155
- items-center
156
- `,
157
- inputClassName = `
158
- InputWithTooltip
159
- h-full
160
- w-[60px]
161
- mr-4
162
- text-center
163
- rounded-md
164
- ${styles.SLIDER_READOUT_FONTSIZE}
165
- `;
166
- if (props.className) {
167
- className += ' ' + props.className;
168
- }
169
- if (minimizeForRow) {
170
- inputClassName += ' h-auto min-h-0 max-h-[50px] mr-1';
171
- }
172
-
173
- return <HStack
174
- className={className}
175
- style={props.style}
176
- >
177
- <InputWithTooltip
178
- {...testProps('readout')}
179
- value={inputValue}
180
- onChangeText={onChangeText}
181
- onKeyPress={onInputKeyPress}
182
- isDisabled={isDisabled}
183
- disableAutoFlex={true}
184
- className={inputClassName}
185
- textAlignIsCenter={true}
186
- {...props._input}
135
+ // convert localValue to string if necessary, because numbers work on web but not mobile; while strings work in both places
136
+ let inputValue = localValue;
137
+ if (_.isNumber(inputValue)) {
138
+ inputValue = '' + inputValue;
139
+ }
140
+
141
+ const style = props.style || {};
142
+ if (!hasWidth(props) && !hasFlex(props)) {
143
+ style.flex = 1;
144
+ }
145
+
146
+ if (sliderValue === 0) {
147
+ sliderValue = FAKE_ZERO; // Slider doesn't like zero
148
+ }
149
+
150
+ let className = `
151
+ w-full
152
+ items-center
153
+ `,
154
+ inputClassName = `
155
+ Input
156
+ h-full
157
+ w-[60px]
158
+ mr-4
159
+ text-center
160
+ rounded-md
161
+ ${styles.SLIDER_READOUT_FONTSIZE}
162
+ `;
163
+ if (props.className) {
164
+ className += ' ' + props.className;
165
+ }
166
+ if (minimizeForRow) {
167
+ inputClassName += ' h-auto min-h-0 max-h-[50px] mr-1';
168
+ }
169
+
170
+ return <HStack
171
+ className={className}
172
+ style={props.style}
173
+ >
174
+ <Input
175
+ {...testProps('readout')}
176
+ value={inputValue}
177
+ onChangeText={onChangeText}
178
+ onKeyPress={onInputKeyPress}
179
+ isDisabled={isDisabled}
180
+ disableAutoFlex={true}
181
+ className={inputClassName}
182
+ textAlignIsCenter={true}
183
+ tooltip={tooltip}
184
+ tooltipPlacement={tooltipPlacement}
185
+ {...props._input}
186
+ />
187
+ <HStack className="flex-1">
188
+ <Slider
189
+ {...testProps('slider')}
190
+ ref={props.outerRef}
191
+ style={{
192
+ width: '100%',
193
+ height: 40,
194
+ }}
195
+ minimumTrackTintColor={styles.SLIDER_MIN_TRACK_COLOR}
196
+ maximumTrackTintColor={styles.SLIDER_MAX_TRACK_COLOR}
197
+ thumbTintColor={styles.SLIDER_THUMB_COLOR}
198
+ minimumValue={minValue}
199
+ maximumValue={maxValue}
200
+ step={step}
201
+ value={sliderValue}
202
+ onValueChange={(value) => {
203
+ // This sets the localValue, only for display purposes
204
+ setLocalValue(value);
205
+ }}
206
+ onSlidingComplete={(value) => {
207
+ // This sets the actual value
208
+ if (value === FAKE_ZERO) {
209
+ value = 0;
210
+ }
211
+ setValue(value);
212
+ }}
187
213
  />
188
- <HStack className="flex-1">
189
- <Slider
190
- {...testProps('slider')}
191
- ref={props.outerRef}
192
- style={{
193
- width: '100%',
194
- height: 40,
195
- }}
196
- minimumTrackTintColor={styles.SLIDER_MIN_TRACK_COLOR}
197
- maximumTrackTintColor={styles.SLIDER_MAX_TRACK_COLOR}
198
- thumbTintColor={styles.SLIDER_THUMB_COLOR}
199
- minimumValue={minValue}
200
- maximumValue={maxValue}
201
- step={step}
202
- value={sliderValue}
203
- onValueChange={(value) => {
204
- // This sets the localValue, only for display purposes
205
- setLocalValue(value);
206
- }}
207
- onSlidingComplete={(value) => {
208
- // This sets the actual value
209
- if (value === FAKE_ZERO) {
210
- value = 0;
211
- }
212
- setValue(value);
213
- }}
214
- />
215
- </HStack>
216
- </HStack>;
217
- },
218
- SliderField = withComponent(withValue(SliderElement));
214
+ </HStack>
215
+ </HStack>;
216
+ };
219
217
 
220
- // Tooltip needs us to forwardRef
221
- export default withTooltip(React.forwardRef((props, ref) => {
222
- return <SliderField {...props} outerRef={ref} />;
223
- }));
218
+ export default withComponent(withValue(SliderElement));
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useRef, } from 'react';
1
+ import { forwardRef, useState, useEffect, useRef, } from 'react';
2
2
  import {
3
3
  Textarea, TextareaInput,
4
4
  } from '@project-components/Gluestack';
@@ -8,106 +8,104 @@ import withTooltip from '../../Hoc/withTooltip.js';
8
8
  import withValue from '../../Hoc/withValue.js';
9
9
  import _ from 'lodash';
10
10
 
11
- const
12
- TextAreaElement = (props) => {
13
- let { // so localValue can be changed, if needed
14
- setValue,
15
- autoSubmit = true, // automatically setValue after user stops typing for autoSubmitDelay
16
- autoSubmitDelay = UiGlobals.autoSubmitDelay,
17
- onChangeText,
18
- placeholder,
19
- minimizeForRow = false,
20
- testID,
21
- } = props,
22
- value = _.isNil(props.value) ? '' : props.value, // null value may not actually reset this TextArea, so set it explicitly to empty string
23
- styles = UiGlobals.styles,
24
- debouncedSetValueRef = useRef(),
25
- [localValue, setLocalValue] = useState(value),
26
- isTypingRef = useRef(),
27
- isTypingTimeoutRef = useRef(),
28
- isTyping = () => {
29
- return isTypingRef.current;
30
- },
31
- setIsTyping = (isTyping) => {
32
- isTypingRef.current = isTyping;
33
- if (isTyping) {
34
- startIsTypingTimeout();
35
- }
36
- },
37
- startIsTypingTimeout = () => {
38
- clearIsTypingTimeout();
39
- isTypingTimeoutRef.current = setTimeout(() => {
40
- setIsTyping(false);
41
- }, autoSubmitDelay + 1000);
42
- },
43
- clearIsTypingTimeout = () => {
44
- if (isTypingTimeoutRef.current) {
45
- clearTimeout(isTypingTimeoutRef.current);
46
- }
47
- },
48
- onChangeTextLocal = (value) => {
49
- setIsTyping(true);
50
- if (value === '') {
51
- value = null; // empty string makes value null
52
- }
53
- setLocalValue(value);
54
- if (autoSubmit) {
55
- debouncedSetValueRef.current(value);
56
- }
57
- if (onChangeText) {
58
- onChangeText(value);
59
- }
60
- };
61
-
62
- useEffect(() => {
63
- // Set up debounce fn
64
- // Have to do this because otherwise, lodash tries to create a debounced version of the fn from only this render
65
- debouncedSetValueRef.current?.cancel(); // Cancel any previous debounced fn
66
- debouncedSetValueRef.current = _.debounce(setValue, autoSubmitDelay);
67
- }, [setValue]);
68
-
69
- useEffect(() => {
70
-
71
- if (!isTyping() && value !== localValue) {
72
- // Make local value conform to externally changed value
73
- setLocalValue(value);
11
+ const TextAreaElement = forwardRef((props, ref) => {
12
+ let { // so localValue can be changed, if needed
13
+ setValue,
14
+ autoSubmit = true, // automatically setValue after user stops typing for autoSubmitDelay
15
+ autoSubmitDelay = UiGlobals.autoSubmitDelay,
16
+ onChangeText,
17
+ placeholder,
18
+ minimizeForRow = false,
19
+ testID,
20
+ className,
21
+ ...propsToPass
22
+ } = props,
23
+ value = _.isNil(props.value) ? '' : props.value, // null value may not actually reset this TextArea, so set it explicitly to empty string
24
+ styles = UiGlobals.styles,
25
+ debouncedSetValueRef = useRef(),
26
+ [localValue, setLocalValue] = useState(value),
27
+ isTypingRef = useRef(),
28
+ isTypingTimeoutRef = useRef(),
29
+ isTyping = () => {
30
+ return isTypingRef.current;
31
+ },
32
+ setIsTyping = (isTyping) => {
33
+ isTypingRef.current = isTyping;
34
+ if (isTyping) {
35
+ startIsTypingTimeout();
36
+ }
37
+ },
38
+ startIsTypingTimeout = () => {
39
+ clearIsTypingTimeout();
40
+ isTypingTimeoutRef.current = setTimeout(() => {
41
+ setIsTyping(false);
42
+ }, autoSubmitDelay + 1000);
43
+ },
44
+ clearIsTypingTimeout = () => {
45
+ if (isTypingTimeoutRef.current) {
46
+ clearTimeout(isTypingTimeoutRef.current);
47
+ }
48
+ },
49
+ onChangeTextLocal = (value) => {
50
+ setIsTyping(true);
51
+ if (value === '') {
52
+ value = null; // empty string makes value null
53
+ }
54
+ setLocalValue(value);
55
+ if (autoSubmit) {
56
+ debouncedSetValueRef.current(value);
57
+ }
58
+ if (onChangeText) {
59
+ onChangeText(value);
74
60
  }
61
+ };
75
62
 
76
- }, [value]);
63
+ useEffect(() => {
64
+ // Set up debounce fn
65
+ // Have to do this because otherwise, lodash tries to create a debounced version of the fn from only this render
66
+ debouncedSetValueRef.current?.cancel(); // Cancel any previous debounced fn
67
+ debouncedSetValueRef.current = _.debounce(setValue, autoSubmitDelay);
68
+ }, [setValue]);
77
69
 
78
- if (localValue === null || typeof localValue === 'undefined') {
79
- localValue = ''; // If the value is null or undefined, don't let this be an uncontrolled input
80
- }
81
- let textareaClassName = `
82
- Textarea
83
- `,
84
- inputClassName = `
85
- TextAreaInput
86
- flex-1
87
- ${styles.FORM_TEXTAREA_CLASSNAME}
88
- `;
89
- if (props.className) {
90
- inputClassName += ' ' + props.className;
91
- }
92
- if (minimizeForRow) {
93
- textareaClassName += ' h-auto min-h-0 max-h-[40px] overflow-auto';
94
- inputClassName += ' py-0';
70
+ useEffect(() => {
71
+
72
+ if (!isTyping() && value !== localValue) {
73
+ // Make local value conform to externally changed value
74
+ setLocalValue(value);
95
75
  }
96
76
 
97
- return <Textarea className={textareaClassName}>
98
- <TextareaInput
99
- testID={testID}
100
- ref={props.outerRef}
101
- onChangeText={onChangeTextLocal}
102
- value={localValue}
103
- className={inputClassName}
104
- placeholder={placeholder}
105
- />
106
- </Textarea>;
107
- },
108
- TextAreaField = withComponent(withValue(TextAreaElement));
77
+ }, [value]);
78
+
79
+ if (localValue === null || typeof localValue === 'undefined') {
80
+ localValue = ''; // If the value is null or undefined, don't let this be an uncontrolled input
81
+ }
82
+ let textareaClassName = `
83
+ Textarea
84
+ `,
85
+ inputClassName = `
86
+ TextAreaInput
87
+ flex-1
88
+ ${styles.FORM_TEXTAREA_CLASSNAME}
89
+ `;
90
+ if (className) {
91
+ inputClassName += ' ' + className;
92
+ }
93
+ if (minimizeForRow) {
94
+ textareaClassName += ' h-auto min-h-0 max-h-[40px] overflow-auto';
95
+ inputClassName += ' py-0';
96
+ }
97
+
98
+ return <Textarea className={textareaClassName}>
99
+ <TextareaInput
100
+ {...propsToPass}
101
+ testID={testID}
102
+ ref={ref}
103
+ onChangeText={onChangeTextLocal}
104
+ value={localValue}
105
+ className={inputClassName}
106
+ placeholder={placeholder}
107
+ />
108
+ </Textarea>;
109
+ });
109
110
 
110
- // withTooltip needs us to forwardRef
111
- export default withTooltip(React.forwardRef((props, ref) => {
112
- return <TextAreaField {...props} outerRef={ref} />;
113
- }));
111
+ export default withComponent(withValue(withTooltip(TextAreaElement)));
@@ -608,12 +608,15 @@ function Form(props) {
608
608
  }
609
609
 
610
610
  if (isEditorViewOnly || !isEditable) {
611
- let value = record?.properties[name]?.displayValue || null;
612
- if (_.isNil(value) && record && record[name]) {
613
- value = record[name];
614
- }
615
- if (_.isNil(value) && startingValues && startingValues[name]) {
616
- value = startingValues[name];
611
+ let value = null;
612
+ if (isSingle) {
613
+ value = record?.properties[name]?.displayValue || null;
614
+ if (_.isNil(value) && record && record[name]) {
615
+ value = record[name];
616
+ }
617
+ if (_.isNil(value) && startingValues && startingValues[name]) {
618
+ value = startingValues[name];
619
+ }
617
620
  }
618
621
 
619
622
  let elementClassName = 'field-' + name;
@@ -455,17 +455,20 @@ function GridComponent(props) {
455
455
  if (isHeaderRow || isReorderMode) {
456
456
  return
457
457
  }
458
+ if (selection && selection[0] && selection[0].isRemotePhantom) {
459
+ return; // block context menu or changing selection when a remote phantom is already selected
460
+ }
458
461
 
459
462
  // context menu
460
- const selection = [item];
463
+ const newSelection = [item];
461
464
  if (!disableWithSelection) {
462
- setSelection(selection);
465
+ setSelection(newSelection);
463
466
  }
464
467
  if (onEditorRowClick) { // e.g. inline editor
465
468
  onEditorRowClick(item, index, e);
466
469
  }
467
470
  if (onContextMenu) {
468
- onContextMenu(item, e, selection);
471
+ onContextMenu(item, e, newSelection);
469
472
  }
470
473
  }}
471
474
  className="Pressable Row flex-row grow">
@@ -50,6 +50,7 @@ export default function withSelection(WrappedComponent) {
50
50
  initialSelection = secondarySelection || secondaryDefaultSelection || [],
51
51
  forceUpdate = useForceUpdate(),
52
52
  secondarySelectionRef = useRef(initialSelection),
53
+ SecondaryRepositoryRef = useRef(SecondaryRepository),
53
54
  [isReady, setIsReady] = useState(secondarySelection || false), // if secondarySelection is already defined, or secondaryValue is not null and we don't need to load repository, it's ready
54
55
  secondarySetSelection = (secondarySelection) => {
55
56
  if (_.isEqual(secondarySelection, secondaryGetSelection())) {
@@ -68,6 +69,9 @@ export default function withSelection(WrappedComponent) {
68
69
  secondaryGetSelection = () => {
69
70
  return secondarySelectionRef.current;
70
71
  },
72
+ secondaryGetRepository = () => {
73
+ return SecondaryRepositoryRef.current;
74
+ },
71
75
  secondarySelectPrev = () => {
72
76
  secondarySelectDirection(SELECT_UP);
73
77
  },
@@ -112,6 +116,7 @@ export default function withSelection(WrappedComponent) {
112
116
  secondarySetSelection(newSelection);
113
117
  },
114
118
  secondaryRemoveFromSelection = (item) => {
119
+ const SecondaryRepository = secondaryGetRepository();
115
120
  let newSelection = [];
116
121
  if (SecondaryRepository) {
117
122
  newSelection = _.remove(secondaryGetSelection(), (sel) => sel !== item);
@@ -132,7 +137,8 @@ export default function withSelection(WrappedComponent) {
132
137
  // That way, after a load event, we'll keep the same selection, if possible.
133
138
  const
134
139
  newSelection = [],
135
- ids = _.map(secondaryGetSelection(), (item) => item.id);
140
+ ids = _.map(secondaryGetSelection(), (item) => item.id),
141
+ SecondaryRepository = secondaryGetRepository();
136
142
  _.each(ids, (id) => {
137
143
  const found = SecondaryRepository.getById(id);
138
144
  if (found) {
@@ -144,6 +150,7 @@ export default function withSelection(WrappedComponent) {
144
150
  getMaxMinSelectionIndices = () => {
145
151
  let items,
146
152
  currentlySelectedRowIndices = [];
153
+ const SecondaryRepository = secondaryGetRepository();
147
154
  if (SecondaryRepository) {
148
155
  items = SecondaryRepository.getEntitiesOnPage();
149
156
  } else {
@@ -194,6 +201,7 @@ export default function withSelection(WrappedComponent) {
194
201
  secondarySetSelection(newSelection);
195
202
  },
196
203
  secondaryIsInSelection = (item) => {
204
+ const SecondaryRepository = secondaryGetRepository();
197
205
  if (SecondaryRepository) {
198
206
  return inArray(item, secondaryGetSelection());
199
207
  }
@@ -204,6 +212,8 @@ export default function withSelection(WrappedComponent) {
204
212
  return !!found;
205
213
  },
206
214
  getIndexOfSelectedItem = (item) => {
215
+ const SecondaryRepository = secondaryGetRepository();
216
+
207
217
  // Gets ix of entity on page, or element in secondaryData array
208
218
  if (SecondaryRepository) {
209
219
  const entities = SecondaryRepository.getEntitiesOnPage();
@@ -223,12 +233,14 @@ export default function withSelection(WrappedComponent) {
223
233
  if (!secondaryGetSelection()[0]) {
224
234
  return null;
225
235
  }
226
- const secondaryValues = _.map(secondaryGetSelection(), (item) => {
227
- if (SecondaryRepository) {
228
- return item.id;
229
- }
230
- return item[secondaryIdIx];
231
- });
236
+ const
237
+ SecondaryRepository = secondaryGetRepository(),
238
+ secondaryValues = _.map(secondaryGetSelection(), (item) => {
239
+ if (SecondaryRepository) {
240
+ return item.id;
241
+ }
242
+ return item[secondaryIdIx];
243
+ });
232
244
  if (secondaryValues.length === 1) {
233
245
  return secondaryValues[0];
234
246
  }
@@ -239,6 +251,7 @@ export default function withSelection(WrappedComponent) {
239
251
  return '';
240
252
  }
241
253
 
254
+ const SecondaryRepository = secondaryGetRepository();
242
255
  return _.map(secondarySelection, (item) => {
243
256
  if (SecondaryRepository) {
244
257
  return item.displayValue;
@@ -258,6 +271,7 @@ export default function withSelection(WrappedComponent) {
258
271
  }
259
272
  },
260
273
  conformSelectionToValue = async () => {
274
+ const SecondaryRepository = secondaryGetRepository();
261
275
  let newSelection = [];
262
276
  if (SecondaryRepository) {
263
277
  if (SecondaryRepository.isLoading) {
@@ -325,6 +339,7 @@ export default function withSelection(WrappedComponent) {
325
339
 
326
340
  (async () => {
327
341
 
342
+ const SecondaryRepository = secondaryGetRepository();
328
343
  if (usesWithValue && SecondaryRepository?.isRemote
329
344
  && !SecondaryRepository.isAutoLoad && !SecondaryRepository.isLoaded && !SecondaryRepository.isLoading && (!_.isNil(secondaryValue) || !_.isEmpty(secondarySelection)) || secondaryAutoSelectFirstItem) {
330
345
  // on initialization, we can't conformSelectionToValue if the repository is not yet loaded,
@@ -5,8 +5,7 @@ import {
5
5
 
6
6
  export default function withMultiSelection(WrappedComponent) {
7
7
  return forwardRef((props, ref) => {
8
- const
9
- {
8
+ const {
10
9
  selectionMode = SELECTION_MODE_MULTI,
11
10
  } = props;
12
11
  return <WrappedComponent
@@ -48,6 +48,7 @@ export default function withSelection(WrappedComponent) {
48
48
  initialSelection = selection || defaultSelection || [],
49
49
  forceUpdate = useForceUpdate(),
50
50
  selectionRef = useRef(initialSelection),
51
+ RepositoryRef = useRef(Repository),
51
52
  [isReady, setIsReady] = useState(selection || false), // if selection is already defined, or value is not null and we don't need to load repository, it's ready
52
53
  setSelection = (selection) => {
53
54
  if (_.isEqual(selection, getSelection())) {
@@ -65,7 +66,10 @@ export default function withSelection(WrappedComponent) {
65
66
  },
66
67
  getSelection = () => {
67
68
  return selectionRef.current;
68
- }
69
+ },
70
+ getRepository = () => {
71
+ return RepositoryRef.current;
72
+ },
69
73
  selectPrev = () => {
70
74
  selectDirection(SELECT_UP);
71
75
  },
@@ -110,6 +114,7 @@ export default function withSelection(WrappedComponent) {
110
114
  setSelection(newSelection);
111
115
  },
112
116
  removeFromSelection = (item) => {
117
+ const Repository = getRepository();
113
118
  let newSelection = [];
114
119
  if (Repository) {
115
120
  newSelection = _.remove(getSelection(), (sel) => sel !== item);
@@ -130,7 +135,8 @@ export default function withSelection(WrappedComponent) {
130
135
  // That way, after a load event, we'll keep the same selection, if possible.
131
136
  const
132
137
  newSelection = [],
133
- ids = _.map(getSelection(), (item) => item.id);
138
+ ids = _.map(getSelection(), (item) => item.id),
139
+ Repository = getRepository();
134
140
  _.each(ids, (id) => {
135
141
  const found = Repository.getById(id);
136
142
  if (found) {
@@ -142,6 +148,7 @@ export default function withSelection(WrappedComponent) {
142
148
  getMaxMinSelectionIndices = () => {
143
149
  let items,
144
150
  currentlySelectedRowIndices = [];
151
+ const Repository = getRepository();
145
152
  if (Repository) {
146
153
  items = Repository.getEntitiesOnPage();
147
154
  } else {
@@ -192,6 +199,7 @@ export default function withSelection(WrappedComponent) {
192
199
  setSelection(newSelection);
193
200
  },
194
201
  isInSelection = (item) => {
202
+ const Repository = getRepository();
195
203
  if (Repository) {
196
204
  return inArray(item, getSelection());
197
205
  }
@@ -202,6 +210,8 @@ export default function withSelection(WrappedComponent) {
202
210
  return !!found;
203
211
  },
204
212
  getIndexOfSelectedItem = (item) => {
213
+ const Repository = getRepository();
214
+
205
215
  // Gets ix of entity on page, or element in data array
206
216
  if (Repository) {
207
217
  const entities = Repository.getEntitiesOnPage();
@@ -221,12 +231,14 @@ export default function withSelection(WrappedComponent) {
221
231
  if (!getSelection()[0]) {
222
232
  return null;
223
233
  }
224
- const values = _.map(getSelection(), (item) => {
225
- if (Repository) {
226
- return item.id;
227
- }
228
- return item[idIx];
229
- });
234
+ const
235
+ Repository = getRepository(),
236
+ values = _.map(getSelection(), (item) => {
237
+ if (Repository) {
238
+ return item.id;
239
+ }
240
+ return item[idIx];
241
+ });
230
242
  if (values.length === 1) {
231
243
  return values[0];
232
244
  }
@@ -237,6 +249,7 @@ export default function withSelection(WrappedComponent) {
237
249
  return '';
238
250
  }
239
251
 
252
+ const Repository = getRepository();
240
253
  return _.map(selection, (item) => {
241
254
  if (Repository) {
242
255
  return item.displayValue;
@@ -256,6 +269,7 @@ export default function withSelection(WrappedComponent) {
256
269
  }
257
270
  },
258
271
  conformSelectionToValue = async () => {
272
+ const Repository = getRepository();
259
273
  let newSelection = [];
260
274
  if (Repository) {
261
275
  if (Repository.isLoading) {
@@ -323,6 +337,7 @@ export default function withSelection(WrappedComponent) {
323
337
 
324
338
  (async () => {
325
339
 
340
+ const Repository = getRepository();
326
341
  if (usesWithValue && Repository?.isRemote
327
342
  && !Repository.isAutoLoad && !Repository.isLoaded && !Repository.isLoading && (!_.isNil(value) || !_.isEmpty(selection)) || autoSelectFirstItem) {
328
343
  // on initialization, we can't conformSelectionToValue if the repository is not yet loaded,
@@ -10,6 +10,7 @@ export default function withTooltip(WrappedComponent) {
10
10
  const {
11
11
  tooltip,
12
12
  tooltipPlacement = 'bottom',
13
+ tooltipClassName,
13
14
  _tooltip = {},
14
15
  ...propsToPass
15
16
  } = props;
@@ -17,7 +18,12 @@ export default function withTooltip(WrappedComponent) {
17
18
  let component = <WrappedComponent {...propsToPass} ref={ref} />;
18
19
 
19
20
  if (tooltip || !_.isEmpty(_tooltip)) {
20
- component = <Tooltip label={tooltip} placement={tooltipPlacement} {..._tooltip}>
21
+ component = <Tooltip
22
+ label={tooltip}
23
+ placement={tooltipPlacement}
24
+ className={tooltipClassName}
25
+ {..._tooltip}
26
+ >
21
27
  {component}
22
28
  </Tooltip>;
23
29
  }
@@ -128,6 +128,7 @@ export default function Pagination(props) {
128
128
  `}
129
129
  textAlignIsCenter={true}
130
130
  tooltip="Set Page"
131
+ tooltipClassName="w-[40px]"
131
132
  />);
132
133
  items.push(<Text
133
134
  key="totalPages"
@@ -1,5 +1,8 @@
1
- import { forwardRef, cloneElement } from 'react';
2
- import { Tooltip, TooltipContent, TooltipText } from '@project-components/Gluestack';
1
+ import { forwardRef } from 'react';
2
+ import {
3
+ BoxNative as Box,
4
+ Tooltip, TooltipContent, TooltipText,
5
+ } from '@project-components/Gluestack';
3
6
 
4
7
  const TooltipElement = forwardRef((props, ref) => {
5
8
  const {
@@ -12,18 +15,18 @@ const TooltipElement = forwardRef((props, ref) => {
12
15
  if (props.className) {
13
16
  className += ' ' + props.className;
14
17
  }
18
+
19
+ let triggerClassName = 'Tooltip-trigger';
20
+ if (props.className) {
21
+ triggerClassName += ' ' + props.className;
22
+ }
15
23
 
16
24
  return <Tooltip
17
25
  placement={placement}
18
26
  trigger={(triggerProps) => {
19
- const propsToPass = {
20
- ...triggerProps,
21
- ...children.props,
22
- };
23
- if (ref) {
24
- propsToPass.ref = ref;
25
- }
26
- return cloneElement(children, propsToPass);
27
+ return <Box className={triggerClassName} {...triggerProps}>
28
+ {children}
29
+ </Box>;
27
30
  }}
28
31
  >
29
32
  <TooltipContent className={className}>
@@ -1,5 +1,5 @@
1
1
  import {
2
- Text,
2
+ TextNative,
3
3
  } from '@project-components/Gluestack';
4
4
  import UiGlobals from '../../UiGlobals';
5
5
 
@@ -16,8 +16,8 @@ export default function MeterTypeText(props) {
16
16
  if (props.className) {
17
17
  className += ' ' + props.className;
18
18
  }
19
- return <Text
19
+ return <TextNative
20
20
  {...props}
21
21
  className={className}
22
- >{props.value ? 'Hours' : 'Miles'}</Text>;
22
+ >{props.value ? 'Time (hrs)' : 'Distance (mi/km)'}</TextNative>;
23
23
  };