@onehat/ui 0.4.86 → 0.4.88

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.86",
3
+ "version": "0.4.88",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -28,6 +28,7 @@ import useForceUpdate from '../../../../Hooks/useForceUpdate.js';
28
28
  import withAlert from '../../../Hoc/withAlert.js';
29
29
  import withComponent from '../../../Hoc/withComponent.js';
30
30
  import withData from '../../../Hoc/withData.js';
31
+ import withTooltip from '../../../Hoc/withTooltip.js';
31
32
  import withValue from '../../../Hoc/withValue.js';
32
33
  import emptyFn from '../../../../Functions/emptyFn.js';
33
34
  import IconButton from '../../../Buttons/IconButton.js';
@@ -100,8 +101,6 @@ export const ComboComponent = forwardRef((props, ref) => {
100
101
  onGridDelete, // to hook into when menu deletes (ComboEditor only)
101
102
  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)
102
103
  newEntityDisplayProperty,
103
- tooltip = null,
104
- tooltipPlacement = 'bottom',
105
104
  testID,
106
105
 
107
106
  // withComponent
@@ -731,14 +730,6 @@ export const ComboComponent = forwardRef((props, ref) => {
731
730
  InputLeftElement={inputIconElement}
732
731
  autoSubmitDelay={500}
733
732
  placeholder={placeholder}
734
- tooltip={tooltip}
735
- tooltipPlacement={tooltipPlacement}
736
- tooltipTriggerClassName={clsx(
737
- 'grow',
738
- 'h-auto',
739
- 'self-stretch',
740
- 'flex-1'
741
- )}
742
733
  className={clsx(
743
734
  'Combo-Input',
744
735
  'grow',
@@ -976,13 +967,6 @@ export const ComboComponent = forwardRef((props, ref) => {
976
967
  InputLeftElement={inputIconElement}
977
968
  autoSubmitDelay={500}
978
969
  placeholder={placeholder}
979
- tooltip={tooltip}
980
- tooltipPlacement={tooltipPlacement}
981
- tooltipTriggerClassName={clsx(
982
- 'grow',
983
- 'h-full',
984
- 'flex-1'
985
- )}
986
970
  className={clsx(
987
971
  'Combo-inputClone-Input',
988
972
  'grow',
@@ -1103,12 +1087,6 @@ export const ComboComponent = forwardRef((props, ref) => {
1103
1087
  InputLeftElement={inputIconElement}
1104
1088
  autoSubmitDelay={500}
1105
1089
  placeholder={placeholder}
1106
- tooltip={tooltip}
1107
- tooltipPlacement={tooltipPlacement}
1108
- tooltipTriggerClassName={clsx(
1109
- 'h-full',
1110
- 'flex-1'
1111
- )}
1112
1090
  className={clsx(
1113
1091
  'h-full',
1114
1092
  'flex-1',
@@ -1282,7 +1260,9 @@ export const Combo = withComponent(
1282
1260
  withAlert(
1283
1261
  withData(
1284
1262
  withValue(
1285
- ComboComponent
1263
+ withTooltip(
1264
+ ComboComponent
1265
+ )
1286
1266
  )
1287
1267
  )
1288
1268
  )
@@ -242,6 +242,7 @@ export const DateElement = forwardRef((props, ref) => {
242
242
  // Format the display date/time/datetime
243
243
  let placeholder = 'Select',
244
244
  pickerValue = null,
245
+ title = null,
245
246
  height = null,
246
247
  width = null;
247
248
  switch(mode) {
@@ -21,6 +21,7 @@ import withComponent from '../../../Hoc/withComponent.js';
21
21
  import withData from '../../../Hoc/withData.js';
22
22
  import withModal from '../../../Hoc/withModal.js';
23
23
  import withValue from '../../../Hoc/withValue.js';
24
+ import withTooltip from '../../../Hoc/withTooltip.js';
24
25
  import ValueBox from './ValueBox.js';
25
26
  import Inflector from 'inflector-js';
26
27
  import Combo, { ComboEditor } from '../Combo/Combo.js';
@@ -42,7 +43,6 @@ function TagComponent(props) {
42
43
  joinDataConfig,
43
44
  getBaseParams, // See note in useEffect
44
45
  outerValueId, // See note in useEffect
45
- tooltip,
46
46
  testID,
47
47
  isDirty = false,
48
48
 
@@ -535,7 +535,6 @@ function TagComponent(props) {
535
535
  onGridAdd={onGridAdd}
536
536
  onGridSave={onGridSave}
537
537
  onGridDelete={onGridDelete}
538
- tooltip={tooltip}
539
538
  usePermissions={props.usePermissions}
540
539
  {..._combo}
541
540
  className={comboClassName}
@@ -559,7 +558,9 @@ export const Tag = withAdditionalProps(
559
558
  withAlert(
560
559
  withData(
561
560
  withValue(
562
- TagComponent
561
+ withTooltip(
562
+ TagComponent
563
+ )
563
564
  )
564
565
  )
565
566
  )
@@ -294,7 +294,12 @@ export default function withFilters(WrappedComponent) {
294
294
  elementProps.minWidth = 100;
295
295
  }
296
296
 
297
- const tooltip = filter.tooltip || title;
297
+ let
298
+ tooltip = filter.tooltip || title,
299
+ placeholder = filter.placeholder || title;
300
+ if (title === tooltip || placeholder === tooltip) {
301
+ tooltip = null;
302
+ }
298
303
  let filterClassName = filterProps.className + ` Filter-${field}`;
299
304
  if (className) {
300
305
  filterClassName += ' ' + className;
@@ -305,7 +310,7 @@ export default function withFilters(WrappedComponent) {
305
310
  let filterElement = <Element
306
311
  {...testProps('filter-' + field)}
307
312
  tooltip={tooltip}
308
- placeholder={tooltip}
313
+ placeholder={placeholder}
309
314
  value={getFilterValue(field)}
310
315
  onChangeValue={(value) => onFilterChangeValue(field, value)}
311
316
  isInFilter={true}
@@ -552,7 +557,7 @@ export default function withFilters(WrappedComponent) {
552
557
  if (isUsingCustomFilters) {
553
558
  _.each(filtersToUse, ({ field, value, getRepoFilters }) => {
554
559
  if (getRepoFilters) {
555
- let repoFiltersFromFilter = getRepoFilters(value) || [];
560
+ let repoFiltersFromFilter = getRepoFilters(value) || []; // getRepoFilters converts the field's value into repository filters (e.g. convert a DateRange field value into two repository filters: >= low, <= high)
556
561
  if (!_.isArray(repoFiltersFromFilter)) {
557
562
  repoFiltersFromFilter = [repoFiltersFromFilter];
558
563
  }
@@ -101,6 +101,7 @@ function TreeComponent(props) {
101
101
  getNodeProps = (item) => {
102
102
  return {};
103
103
  },
104
+ fitToContainerWidth = false,
104
105
  noneFoundText,
105
106
  disableLoadingIndicator = false,
106
107
  disableSelectorSelected = false,
@@ -1349,6 +1350,7 @@ function TreeComponent(props) {
1349
1350
  nodeCanSelect={nodeCanSelect}
1350
1351
  nodeCanDrag={nodeCanDrag}
1351
1352
  isHighlighted={highlitedDatum === datum}
1353
+ fitToContainerWidth={fitToContainerWidth}
1352
1354
  {...nodeDragProps}
1353
1355
 
1354
1356
  // fields={fields}
@@ -1504,7 +1506,7 @@ function TreeComponent(props) {
1504
1506
  'Tree-VStack',
1505
1507
  'flex-1',
1506
1508
  'w-full',
1507
- 'min-w-[300px]',
1509
+ fitToContainerWidth ? 'min-w-0' : 'min-w-[300px]',
1508
1510
  );
1509
1511
  if (isLoading) {
1510
1512
  className += ' border-t-2 border-[#f00]';
@@ -1542,8 +1544,9 @@ function TreeComponent(props) {
1542
1544
  >
1543
1545
  <ScrollView
1544
1546
  {...testProps('ScrollView-Horizontal')}
1545
- horizontal={true}
1547
+ horizontal={!fitToContainerWidth}
1546
1548
  className="w-full"
1549
+ showsHorizontalScrollIndicator={!fitToContainerWidth}
1547
1550
  contentContainerStyle={{
1548
1551
  minWidth: '100%',
1549
1552
  flexDirection: 'column', // Keep vertical stacking
@@ -37,6 +37,7 @@ export default function TreeNode(props) {
37
37
  nodeProps = {},
38
38
  onToggle,
39
39
  bg,
40
+ fitToContainerWidth,
40
41
  isDraggable,
41
42
  isDragSource,
42
43
  isHovered,
@@ -132,6 +133,10 @@ export default function TreeNode(props) {
132
133
  !showNodeHandle && 'select-none',
133
134
  'cursor-pointer',
134
135
  );
136
+ if (fitToContainerWidth) {
137
+ // ensure node occupies container width and allows children to wrap instead of forcing a wider row
138
+ className += ' w-full min-w-0 flex-wrap';
139
+ }
135
140
 
136
141
  // Add drop state classes for additional styling
137
142
  if (isOver && actualCanDrop) {
@@ -151,6 +156,9 @@ export default function TreeNode(props) {
151
156
  className={className}
152
157
  style={{
153
158
  backgroundColor: bg,
159
+ // if fitToContainerWidth, lock to 100% width and allow wrapping; don't forcibly hide content
160
+ width: fitToContainerWidth ? '100%' : undefined,
161
+ minWidth: fitToContainerWidth ? 0 : undefined,
154
162
  }}
155
163
  ref={(element) => {
156
164
  if (dropTargetRef && dropTargetRef.current !== undefined) {
@@ -210,22 +218,24 @@ export default function TreeNode(props) {
210
218
  />}
211
219
 
212
220
  {text && <TextNative
213
- numberOfLines={1}
214
- ellipsizeMode="head"
221
+ // allow multi-line wrapping instead of truncation so content can wrap to available width
222
+ // removed numberOfLines and ellipsizeMode to allow wrapping
215
223
  // {...propsToPass}
216
224
  className={clsx(
217
225
  'TreeNode-TextNative',
218
226
  'self-center',
219
- 'overflow-hidden',
227
+ 'overflow-visible',
220
228
  'flex',
221
229
  'flex-1',
222
- 'text-ellipsis',
230
+ 'min-w-0',
231
+ 'break-words',
232
+ 'whitespace-normal',
223
233
  styles.TREE_NODE_CLASSNAME,
224
234
  nodeProps?._text?.className ?? null,
225
235
  )}
226
236
  >{text}</TextNative>}
227
237
 
228
- {content}
238
+ {content && <Box className="flex-1 min-w-0 break-words whitespace-normal">{content}</Box>}
229
239
 
230
240
  </HStackNative>;
231
241
  }, [
@@ -233,6 +243,8 @@ export default function TreeNode(props) {
233
243
  bg,
234
244
  item,
235
245
  hash, // this is an easy way to determine if the data has changed and the item needs to be rerendered
246
+ fitToContainerWidth,
247
+ isDraggable,
236
248
  isDragSource,
237
249
  isExpanded,
238
250
  isHighlighted,