@onehat/ui 0.4.71 → 0.4.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/package.json +2 -1
  2. package/src/Components/Buttons/Button.js +20 -6
  3. package/src/Components/Container/ScreenContainer.js +1 -0
  4. package/src/Components/Editor/InlineEditor.js +2 -1
  5. package/src/Components/Form/Field/Color.js +2 -1
  6. package/src/Components/Form/Field/Combo/Combo.js +55 -37
  7. package/src/Components/Form/Field/Combo/MeterTypesCombo.js +4 -2
  8. package/src/Components/Form/Field/Date.js +9 -8
  9. package/src/Components/Form/Field/Input.js +5 -4
  10. package/src/Components/Form/Field/Json.js +3 -2
  11. package/src/Components/Form/Field/TextArea.js +1 -1
  12. package/src/Components/Form/FieldSet.js +1 -1
  13. package/src/Components/Form/Form.js +4 -1
  14. package/src/Components/Gluestack/accordion/index.tsx +5 -1
  15. package/src/Components/Gluestack/actionsheet/index.tsx +5 -1
  16. package/src/Components/Gluestack/alert/index.tsx +5 -1
  17. package/src/Components/Gluestack/badge/index.tsx +5 -1
  18. package/src/Components/Gluestack/button/index.tsx +5 -1
  19. package/src/Components/Gluestack/checkbox/index.tsx +5 -1
  20. package/src/Components/Gluestack/fab/index.tsx +5 -1
  21. package/src/Components/Gluestack/form-control/index.tsx +5 -1
  22. package/src/Components/Gluestack/icon/createIcon.js +74 -0
  23. package/src/Components/Gluestack/icon/index.tsx +46 -88
  24. package/src/Components/Gluestack/input/index.tsx +5 -1
  25. package/src/Components/Gluestack/select/index.tsx +5 -1
  26. package/src/Components/Grid/Grid.js +24 -11
  27. package/src/Components/Grid/GridHeaderRow.js +4 -3
  28. package/src/Components/Grid/GridRow.js +35 -34
  29. package/src/Components/Grid/RowDragHandle.js +25 -10
  30. package/src/Components/Grid/RowHandle.js +55 -0
  31. package/src/{Hooks → Components/Grid}/useAsyncRenderers.js +1 -1
  32. package/src/Components/Hoc/Secondary/withSecondaryData.js +2 -1
  33. package/src/Components/Hoc/Secondary/withSecondaryEditor.js +3 -2
  34. package/src/Components/Hoc/Secondary/withSecondarySelection.js +3 -2
  35. package/src/Components/Hoc/Secondary/withSecondaryValue.js +2 -1
  36. package/src/Components/Hoc/withAlert.js +21 -11
  37. package/src/Components/Hoc/withCollapsible.js +9 -4
  38. package/src/Components/Hoc/withComponent.js +6 -0
  39. package/src/Components/Hoc/withContextMenu.js +6 -0
  40. package/src/Components/Hoc/withData.js +3 -2
  41. package/src/Components/Hoc/withDnd.js +52 -40
  42. package/src/Components/Hoc/withDraggable.js +21 -5
  43. package/src/Components/Hoc/withEditor.js +2 -1
  44. package/src/Components/Hoc/withEvents.js +11 -1
  45. package/src/Components/Hoc/withFilters.js +7 -2
  46. package/src/Components/Hoc/withModal.js +3 -2
  47. package/src/Components/Hoc/withPdfButtons.js +3 -2
  48. package/src/Components/Hoc/withPermissions.js +3 -2
  49. package/src/Components/Hoc/withPresetButtons.js +3 -2
  50. package/src/Components/Hoc/withSelection.js +2 -8
  51. package/src/Components/Hoc/withToast.js +4 -2
  52. package/src/Components/Hoc/withTooltip.js +10 -1
  53. package/src/Components/Hoc/withValue.js +3 -9
  54. package/src/Components/Messages/GlobalModals.js +70 -0
  55. package/src/Components/Messages/Loading.js +2 -2
  56. package/src/Components/Messages/ProgressModal.js +63 -0
  57. package/src/Components/Messages/WaitMessage.js +7 -2
  58. package/src/Components/Report/Report.js +15 -5
  59. package/src/Components/Toolbar/Pagination.js +1 -1
  60. package/src/Components/Toolbar/Toolbar.js +26 -6
  61. package/src/Components/Tree/Tree.js +22 -6
  62. package/src/Components/Tree/TreeNode.js +11 -11
  63. package/src/Components/Tree/TreeNodeDragHandle.js +8 -4
  64. package/src/Components/Viewer/MeterTypeText.js +21 -1
  65. package/src/Components/Viewer/TextWithLinks.js +2 -1
  66. package/src/Constants/Dates.js +5 -2
  67. package/src/Constants/MeterTypes.js +2 -0
  68. package/src/Functions/addIconProps.js +46 -0
  69. package/src/Functions/downloadInBackground.js +47 -7
  70. package/src/Functions/getReport.js +5 -2
  71. package/src/Functions/testProps.js +1 -1
  72. package/src/Functions/trackEngagementHit.js +2 -1
  73. package/src/Hooks/useWhyDidYouUpdate.js +33 -0
  74. package/src/PlatformImports/Web/Attachments.js +1 -1
  75. package/src/Components/Hoc/withBlank.js +0 -10
@@ -0,0 +1,74 @@
1
+ import React, { forwardRef } from 'react';
2
+ import { Path, G } from 'react-native-svg';
3
+ const ChildPath = ({ element, fill, stroke: pathStroke }) => {
4
+ const pathStrokeColor = pathStroke || '';
5
+ const fillColor = fill || '';
6
+ if (!element) {
7
+ return null;
8
+ }
9
+ if (element.type === React.Fragment) {
10
+ return element;
11
+ }
12
+ return React.cloneElement(element, {
13
+ fill: fillColor ? fillColor : 'currentColor',
14
+ stroke: pathStrokeColor,
15
+ });
16
+ };
17
+ export function createIcon({ Root, path, d, ...initialProps }) {
18
+ const IconTemp = forwardRef((props, ref) => {
19
+ let children = path;
20
+ if (d && (!path || Object.keys(path).length === 0)) {
21
+ children = <Path fill="currentColor" d={d}/>;
22
+ }
23
+ const finalProps = {
24
+ ...initialProps,
25
+ ...props,
26
+ };
27
+ const {
28
+ stroke = 'currentColor',
29
+ // BEGIN SKOTE MOD
30
+ fill,
31
+ // END SKOTE MOD
32
+ color,
33
+ role = 'img',
34
+ ...resolvedProps
35
+ } = finalProps;
36
+ let type = resolvedProps.type;
37
+ if (type === undefined) {
38
+ type = 'svg';
39
+ }
40
+ let colorProps = {};
41
+ if (color) {
42
+ colorProps = { ...colorProps, color: color };
43
+ }
44
+ if (stroke) {
45
+ colorProps = { ...colorProps, stroke: stroke };
46
+ }
47
+ let sizeProps = {};
48
+ let sizeStyle = {};
49
+ if (type === 'font') {
50
+ if (resolvedProps.sx) {
51
+ sizeProps = { ...sizeProps, fontSize: resolvedProps?.sx?.h };
52
+ }
53
+ if (resolvedProps.size) {
54
+ // sizeProps = { ...sizeProps, fontSize: resolvedProps?.size };
55
+ }
56
+ }
57
+ return (<Root {...resolvedProps} {...colorProps} role={role} ref={ref} {...sizeProps} {...sizeStyle}>
58
+ {React.Children.count(children) > 0 ? (<G>
59
+ {React.Children.map(children, (child, i) => (
60
+ <ChildPath
61
+ key={child?.key ?? i}
62
+ element={child}
63
+ {...child?.props}
64
+ // BEGIN SKOTE MOD
65
+ fill={fill || child?.props?.fill}
66
+ // END SKOTE MOD
67
+ />
68
+ ))}
69
+ </G>) : null}
70
+ </Root>);
71
+ });
72
+ const Icon = IconTemp;
73
+ return Icon;
74
+ }
@@ -1,75 +1,29 @@
1
1
  'use client';
2
- import React, { useMemo } from 'react';
3
- import { createIcon } from '@gluestack-ui/icon';
4
- import { Path, Svg } from 'react-native-svg';
2
+ import React from 'react';
3
+ // BEGIN SKOTE MOD
4
+ // See my comment here: https://github.com/gluestack/gluestack-ui/issues/2385#issuecomment-3141973446
5
+ // import { createIcon } from '@gluestack-ui/icon';
6
+ import { createIcon } from './createIcon.js';
7
+ // END SKOTE MOD
8
+ import { Path } from 'react-native-svg';
5
9
  import { tva } from '@gluestack-ui/nativewind-utils/tva';
6
10
  import { cssInterop } from 'nativewind';
7
11
  import { VariantProps } from '@gluestack-ui/nativewind-utils';
8
-
9
- type IPrimitiveIcon = {
10
- height?: number | string;
11
- width?: number | string;
12
- fill?: string;
13
- color?: string;
14
- size?: number | string;
15
- stroke?: string;
16
- as?: React.ElementType;
17
- className?: string;
18
- classNameColor?: string;
19
- };
20
-
21
- const PrimitiveIcon = React.forwardRef<
22
- React.ElementRef<typeof Svg>,
23
- IPrimitiveIcon
24
- >(
25
- (
26
- {
27
- height,
28
- width,
29
- fill,
30
- color,
31
- classNameColor,
32
- size,
33
- stroke,
34
- as: AsComp,
35
- ...props
36
- },
37
- ref
38
- ) => {
39
- color = color ?? classNameColor;
40
- const sizeProps = useMemo(() => {
41
- if (size) return { size };
42
- if (height && width) return { height, width };
43
- if (height) return { height };
44
- if (width) return { width };
45
- return {};
46
- }, [size, height, width]);
47
-
48
- let colorProps = {};
49
- if (fill) {
50
- colorProps = { ...colorProps, fill: fill };
51
- }
52
- if (stroke !== 'currentColor') {
53
- colorProps = { ...colorProps, stroke: stroke };
54
- } else if (stroke === 'currentColor' && color !== undefined) {
55
- colorProps = { ...colorProps, stroke: color };
56
- }
57
-
58
- if (AsComp) {
59
- return <AsComp ref={ref} {...props} {...sizeProps} {...colorProps} />;
60
- }
61
- return (
62
- <Svg ref={ref} height={height} width={width} {...colorProps} {...props} />
63
- );
64
- }
65
- );
12
+ import { PrimitiveIcon, IPrimitiveIcon, Svg } from '@gluestack-ui/icon';
66
13
 
67
14
  export const UIIcon = createIcon({
68
15
  Root: PrimitiveIcon,
69
- });
16
+ }) as React.ForwardRefExoticComponent<
17
+ React.ComponentPropsWithoutRef<typeof PrimitiveIcon> &
18
+ React.RefAttributes<React.ComponentRef<typeof Svg>>
19
+ >;
70
20
 
71
21
  const iconStyle = tva({
72
- base: 'text-typography-950 fill-none pointer-events-none',
22
+ // BEGIN SKOTE MOD
23
+ // See https://github.com/gluestack/gluestack-ui/issues/2385#issuecomment-3141973446
24
+ // base: 'text-typography-950 fill-none pointer-events-none',
25
+ base: 'text-typography-950 fill-black pointer-events-none',
26
+ // END SKOTE MOD
73
27
  variants: {
74
28
  size: {
75
29
  '2xs': 'h-3 w-3',
@@ -82,7 +36,6 @@ const iconStyle = tva({
82
36
  },
83
37
  });
84
38
 
85
- // @ts-expect-error
86
39
  cssInterop(UIIcon, {
87
40
  className: {
88
41
  target: 'style',
@@ -100,8 +53,8 @@ type IIConProps = IPrimitiveIcon &
100
53
  VariantProps<typeof iconStyle> &
101
54
  React.ComponentPropsWithoutRef<typeof UIIcon>;
102
55
 
103
- export const Icon = React.forwardRef<React.ElementRef<typeof Svg>, IIConProps>(
104
- ({ size = 'md', className, ...props }, ref) => {
56
+ const Icon = React.forwardRef<React.ComponentRef<typeof UIIcon>, IIConProps>(
57
+ function Icon({ size = 'md', className, ...props }, ref) {
105
58
  if (typeof size === 'number') {
106
59
  return (
107
60
  <UIIcon
@@ -133,31 +86,36 @@ export const Icon = React.forwardRef<React.ElementRef<typeof Svg>, IIConProps>(
133
86
  }
134
87
  );
135
88
 
89
+ export { Icon };
90
+
136
91
  type ParameterTypes = Omit<Parameters<typeof createIcon>[0], 'Root'>;
137
92
 
138
93
  const createIconUI = ({ ...props }: ParameterTypes) => {
139
- const UIIconCreateIcon = createIcon({ Root: Svg, ...props });
140
-
141
- return React.forwardRef<React.ElementRef<typeof Svg>>(
142
- (
143
- {
144
- className,
145
- size,
146
- ...props
147
- }: VariantProps<typeof iconStyle> &
148
- React.ComponentPropsWithoutRef<typeof UIIconCreateIcon>,
149
- ref
150
- ) => {
151
- return (
152
- <UIIconCreateIcon
153
- // @ts-ignore
154
- ref={ref}
155
- {...props}
156
- className={iconStyle({ size, class: className })}
157
- />
158
- );
159
- }
160
- );
94
+ const UIIconCreateIcon = createIcon({
95
+ Root: Svg,
96
+ ...props,
97
+ }) as React.ForwardRefExoticComponent<
98
+ React.ComponentPropsWithoutRef<typeof PrimitiveIcon> &
99
+ React.RefAttributes<React.ComponentRef<typeof Svg>>
100
+ >;
101
+
102
+ return React.forwardRef<React.ComponentRef<typeof Svg>>(function UIIcon(
103
+ {
104
+ className,
105
+ size,
106
+ ...inComingProps
107
+ }: VariantProps<typeof iconStyle> &
108
+ React.ComponentPropsWithoutRef<typeof UIIconCreateIcon>,
109
+ ref
110
+ ) {
111
+ return (
112
+ <UIIconCreateIcon
113
+ ref={ref}
114
+ {...inComingProps}
115
+ className={iconStyle({ size, class: className })}
116
+ />
117
+ );
118
+ });
161
119
  };
162
120
  export { createIconUI as createIcon };
163
121
  // All Icons
@@ -115,7 +115,11 @@ const inputStyle = tva({
115
115
  });
116
116
 
117
117
  const inputIconStyle = tva({
118
- base: 'justify-center items-center text-typography-400 fill-none',
118
+ // BEGIN SKOTE MOD
119
+ // See https://github.com/gluestack/gluestack-ui/issues/2385#issuecomment-3141973446
120
+ // base: 'justify-center items-center text-typography-400 fill-none',
121
+ base: 'justify-center items-center text-typography-400 fill-black',
122
+ // END SKOTE MOD
119
123
  parentVariants: {
120
124
  size: {
121
125
  '2xs': 'h-3 w-3',
@@ -33,7 +33,11 @@ const SelectTriggerWrapper = React.forwardRef<
33
33
  });
34
34
 
35
35
  const selectIconStyle = tva({
36
- base: 'text-background-500 fill-none',
36
+ // BEGIN SKOTE MOD
37
+ // See https://github.com/gluestack/gluestack-ui/issues/2385#issuecomment-3141973446
38
+ // base: 'text-background-500 fill-none',
39
+ base: 'text-background-500 fill-black',
40
+ // END SKOTE MOD
37
41
  parentVariants: {
38
42
  size: {
39
43
  '2xs': 'h-3 w-3',
@@ -35,7 +35,6 @@ import {
35
35
  hasFlex,
36
36
  } from '../../Functions/tailwindFunctions.js';
37
37
  import * as yup from 'yup'; // https://github.com/jquense/yup#string
38
- import Inflector from 'inflector-js';
39
38
  import { EDITOR_TYPE__PLAIN } from '../../Constants/Editor.js';
40
39
  import UiGlobals from '../../UiGlobals.js';
41
40
  import useForceUpdate from '../../Hooks/useForceUpdate.js';
@@ -113,11 +112,15 @@ function GridComponent(props) {
113
112
  columnProps = {},
114
113
  defaultHiddenColumns = [],
115
114
  getRowProps = (item) => {
115
+ let className = clsx(
116
+ 'border-bottom-1',
117
+ 'border-bottom-grey-500',
118
+ );
119
+ if (CURRENT_MODE === UI_MODE_NATIVE) {
120
+ className += ' py-4';
121
+ }
116
122
  return {
117
- className: clsx(
118
- 'border-bottom-1',
119
- 'border-bottom-grey-500',
120
- ),
123
+ className,
121
124
  };
122
125
  },
123
126
  flatListProps = {},
@@ -171,6 +174,7 @@ function GridComponent(props) {
171
174
 
172
175
  // DND
173
176
  canRowsReorder = false,
177
+ canRowDrag, // optional fn to customize whether each row can be dragged
174
178
  canRowAcceptDrop, // optional fn to customize whether each node can accept a dropped item: (targetItem, draggedItem) => boolean
175
179
  getCustomDragProxy, // optional fn to render custom drag preview: (item, selection) => ReactElement
176
180
  dragPreviewOptions, // optional object for drag preview positioning options
@@ -540,6 +544,7 @@ function GridComponent(props) {
540
544
  rowReorderProps.dragSourceItem = {
541
545
  id: item.id,
542
546
  getSelection,
547
+ isInSelection,
543
548
  onDrag: (dragState) => {
544
549
  onRowReorderDrag(dragState, dragIx);
545
550
  },
@@ -547,20 +552,30 @@ function GridComponent(props) {
547
552
  rowReorderProps.onDragEnd = onRowReorderEnd;
548
553
  } else {
549
554
  // Don't allow drag/drop from withDnd while reordering
550
- if (areRowsDragSource) {
555
+ if (areRowsDragSource && (!canRowDrag || canRowDrag(item))) {
551
556
  WhichRow = DragSourceGridRow;
552
557
  rowDragProps.isDragSource = true;
553
558
  rowDragProps.dragSourceType = rowDragSourceType;
554
559
  if (getRowDragSourceItem) {
555
- rowDragProps.dragSourceItem = getRowDragSourceItem(item, getSelection, rowDragSourceType);
560
+ rowDragProps.dragSourceItem = getRowDragSourceItem(item, getSelection, isInSelection, rowDragSourceType);
556
561
  } else {
557
562
  rowDragProps.dragSourceItem = {
558
563
  id: item.id,
559
564
  item,
560
565
  getSelection,
566
+ isInSelection,
561
567
  type: rowDragSourceType,
562
568
  };
563
569
  }
570
+ rowDragProps.dragSourceItem.onDragStart = () => {
571
+ if (!isInSelection(item)) { // get updated isSelected (will be stale if using one in closure)
572
+ // reset the selection to just this one node if it's not already selected
573
+ setSelection([item]);
574
+ }
575
+ };
576
+ if (canRowDrag) {
577
+ rowDragProps.canDrag = () => canRowDrag(item, rowDragProps.dragSourceItem);
578
+ }
564
579
 
565
580
  // Add custom drag preview options
566
581
  if (dragPreviewOptions) {
@@ -697,8 +712,7 @@ function GridComponent(props) {
697
712
  };
698
713
  },
699
714
  buildCachedDragElements = (dragState) => {
700
- const
701
- {
715
+ const {
702
716
  canDrag,
703
717
  isDragging,
704
718
  clientOffset,
@@ -747,8 +761,7 @@ function GridComponent(props) {
747
761
  cachedDragElements.current = buildCachedDragElements(dragState);
748
762
  }
749
763
 
750
- const
751
- {
764
+ const {
752
765
  canDrag,
753
766
  isDragging,
754
767
  clientOffset,
@@ -15,6 +15,7 @@ import {
15
15
  HORIZONTAL,
16
16
  } from '../../Constants/Directions.js';
17
17
  import {
18
+ CURRENT_MODE,
18
19
  UI_MODE_WEB,
19
20
  } from '../../Constants/UiModes.js';
20
21
  import UiGlobals from '../../UiGlobals.js';
@@ -280,7 +281,7 @@ export default function GridHeaderRow(props) {
280
281
  }
281
282
  }, [columnsConfig]);
282
283
 
283
- if (UiGlobals.mode !== UI_MODE_WEB) {
284
+ if (CURRENT_MODE !== UI_MODE_WEB) {
284
285
  canColumnsReorder = false;
285
286
  canColumnsResize = false;
286
287
  }
@@ -407,7 +408,7 @@ export default function GridHeaderRow(props) {
407
408
  'overflow-hidden',
408
409
  'text-ellipsis',
409
410
  'px-2',
410
- py-3,
411
+ 'py-3',
411
412
  styles.GRID_HEADER_CLASSNAME,
412
413
  )}
413
414
  >{header}</TextNative>
@@ -425,7 +426,7 @@ export default function GridHeaderRow(props) {
425
426
  )}
426
427
  />}
427
428
 
428
- {isOver && UiGlobals.mode === UI_MODE_WEB && // only works for web for now
429
+ {isOver && CURRENT_MODE === UI_MODE_WEB && // only works for web for now
429
430
  <HeaderColumnSelectorHandle
430
431
  key="HeaderColumnSelectorHandle"
431
432
  showColumnsSelector={showColumnsSelector}
@@ -20,9 +20,8 @@ import { withDragSource, withDropTarget } from '../Hoc/withDnd.js';
20
20
  import testProps from '../../Functions/testProps.js';
21
21
  import Loading from '../Messages/Loading.js';
22
22
  import AngleRight from '../Icons/AngleRight.js';
23
- import RowDragHandle from './RowDragHandle.js';
24
- import RowSelectHandle from './RowSelectHandle.js';
25
- import useAsyncRenderers from '../../Hooks/useAsyncRenderers.js';
23
+ import RowHandle from './RowHandle.js';
24
+ import useAsyncRenderers from './useAsyncRenderers.js';
26
25
  import _ from 'lodash';
27
26
 
28
27
  // Conditional import for web only
@@ -45,7 +44,6 @@ function GridRow(props) {
45
44
  rowProps,
46
45
  hideNavColumn,
47
46
  showSelectHandle,
48
- isRowSelectable,
49
47
  isRowHoverable,
50
48
  isSelected,
51
49
  isHovered,
@@ -102,7 +100,7 @@ function GridRow(props) {
102
100
  actualCanDrop = validateDrop(draggedItem);
103
101
  }
104
102
 
105
- if (isRowSelectable && isSelected) {
103
+ if (isSelected) {
106
104
  if (showHovers && isHovered) {
107
105
  mixWith = styles.GRID_ROW_SELECTED_BG_HOVER;
108
106
  } else {
@@ -198,13 +196,33 @@ function GridRow(props) {
198
196
  };
199
197
 
200
198
  let content = null;
199
+ let textClassName = clsx(
200
+ 'GridRow-TextNative',
201
+ 'self-center',
202
+ 'overflow-hidden',
203
+ colClassName,
204
+ styles.GRID_CELL_CLASSNAME,
205
+ styles.GRID_ROW_MAX_HEIGHT_EXTRA,
206
+ );
207
+ if (config.className) {
208
+ textClassName += ' ' + config.className;
209
+ }
210
+ const rendererProps = {
211
+ ...testProps('rendererCol-' + config.fieldName),
212
+ className: textClassName,
213
+ ...propsToPass,
214
+ ...extraProps,
215
+ style: colStyle,
216
+ };
201
217
  if (config.isAsync) {
218
+ // TODO: Figure out how to pass the rendererProps to the async renderer function
219
+ throw Error('Not yet working correctly!');
202
220
  // Async renderer
203
221
  if (isLoading) {
204
222
  content = <Loading />;
205
223
  } else if (asyncResult) {
206
224
  if (asyncResult.error) {
207
- content = <Text>Render Error: {asyncResult.error.message || String(asyncResult.error)}</Text>;
225
+ content = <Text key={key}>Render Error: {asyncResult.error.message || String(asyncResult.error)}</Text>;
208
226
  } else {
209
227
  content = asyncResult.result;
210
228
  }
@@ -212,24 +230,17 @@ function GridRow(props) {
212
230
  } else {
213
231
  // Synchronous renderer
214
232
  try {
215
- const result = config.renderer(item);
233
+ const result = config.renderer(item, config.fieldName, rendererProps, key);
216
234
  if (result && typeof result.then === 'function') {
217
- content = <Text>Error: Async renderer not properly configured</Text>;
235
+ content = <Text key={key}>Error: Async renderer not properly configured</Text>;
218
236
  } else {
219
237
  content = result;
220
238
  }
221
239
  } catch (error) {
222
- content = <Text>Render Error: {error}</Text>;
240
+ content = <Text key={key}>Render Error: {error}</Text>;
223
241
  }
224
242
  }
225
- return <HStackNative
226
- key={key}
227
- {...testProps('rendererCol-' + key)}
228
- className={colClassName}
229
- {...propsToPass}
230
- {...extraProps}
231
- style={colStyle}
232
- >{content}</HStackNative>;
243
+ return content;
233
244
  }
234
245
  if (config.fieldName) {
235
246
 
@@ -342,8 +353,13 @@ function GridRow(props) {
342
353
  };
343
354
 
344
355
  let rowContents = <>
345
- {(isDragSource || isDraggable) && <RowDragHandle />}
346
- {showSelectHandle && <RowSelectHandle />}
356
+ {(isDragSource || isDraggable || showSelectHandle) &&
357
+ <RowHandle
358
+ ref={dragSourceRef}
359
+ isDragSource={isDragSource}
360
+ isDraggable={isDraggable}
361
+ showSelectHandle={showSelectHandle}
362
+ />}
347
363
 
348
364
  {isPhantom &&
349
365
  <Box
@@ -373,21 +389,6 @@ function GridRow(props) {
373
389
  )}
374
390
  />}
375
391
  </>;
376
-
377
- if (dragSourceRef) {
378
- rowContents = <HStack
379
- ref={dragSourceRef}
380
- className={clsx(
381
- 'GridRow-dragSourceRef',
382
- 'w-full',
383
- 'flex-1',
384
- 'grow-1',
385
- )}
386
- style={{
387
- backgroundColor: bg,
388
- }}
389
- >{rowContents}</HStack>;
390
- }
391
392
  if (dropTargetRef) {
392
393
  rowContents = <HStack
393
394
  ref={dropTargetRef}
@@ -1,3 +1,4 @@
1
+ import { forwardRef } from 'react';
1
2
  import {
2
3
  Icon,
3
4
  VStack,
@@ -6,15 +7,29 @@ import clsx from 'clsx';
6
7
  import styles from '../../Styles/StyleSheets.js';
7
8
  import GripVertical from '../Icons/GripVertical.js';
8
9
 
9
- function RowDragHandle(props) { return <VStack
10
- style={styles.ewResize}
11
- className="RowDragHandle bg-grey-100 w-[7px] items-center justify-center select-none"
12
- >
13
- <Icon
14
- as={GripVertical}
15
- size="xs"
16
- className="handle w-full h-full text-[#ccc]" />
17
- </VStack>;
18
- }
10
+ const RowDragHandle = forwardRef(function(props, ref) {
11
+ let className = clsx(
12
+ 'RowDragHandle',
13
+ 'bg-grey-100',
14
+ 'w-[17px]',
15
+ 'items-center',
16
+ 'justify-center',
17
+ 'select-none',
18
+ );
19
+ if (props.className) {
20
+ className += ' ' + props.className;
21
+ }
22
+ return <VStack
23
+ {...props}
24
+ ref={ref}
25
+ style={styles.ewResize}
26
+ className={className}
27
+ >
28
+ <Icon
29
+ as={GripVertical}
30
+ size="xs"
31
+ className="handle w-full h-full text-[#ccc]" />
32
+ </VStack>;
33
+ });
19
34
 
20
35
  export default RowDragHandle;
@@ -0,0 +1,55 @@
1
+ import { forwardRef } from 'react';
2
+ import {
3
+ Icon,
4
+ VStack,
5
+ } from '@project-components/Gluestack';
6
+ import withTooltip from '@onehat/ui/src/Components/Hoc/withTooltip';
7
+ import clsx from 'clsx';
8
+ import Arcs from '../Icons/Arcs.js';
9
+
10
+ const RowHandle = forwardRef(function RowHandle(props, ref) {
11
+ const {
12
+ isDragSource,
13
+ isDraggable
14
+ } = props;
15
+ let className = clsx(
16
+ 'RowHandle',
17
+ 'h-full',
18
+ 'w-[40px]',
19
+ 'px-2',
20
+ 'items-center',
21
+ 'justify-center',
22
+ 'select-none',
23
+ 'cursor-pointer'
24
+ );
25
+ return <VStack
26
+ ref={isDragSource || isDraggable ? ref : undefined}
27
+ className={className}
28
+ >
29
+ <Icon as={Arcs} size="xs" className="w-full h-full text-[#ddd]" />
30
+ </VStack>;
31
+ });
32
+
33
+ function withAdditionalProps(WrappedComponent) {
34
+ return (props) => {
35
+ const {
36
+ showSelectHandle,
37
+ isDragSource,
38
+ isDraggable
39
+ } = props;
40
+ let tooltipParts = [];
41
+ if (showSelectHandle) {
42
+ tooltipParts.push('Select');
43
+ }
44
+ if (isDragSource || isDraggable) {
45
+ tooltipParts.push('Drag');
46
+ }
47
+ const tooltip = tooltipParts.length === 2 ? tooltipParts.join(' or ') : tooltipParts[0];
48
+ return <WrappedComponent
49
+ tooltip={tooltip}
50
+ {...props}
51
+ />;
52
+ };
53
+ }
54
+
55
+ export default withAdditionalProps(withTooltip(RowHandle));
@@ -7,7 +7,7 @@ export default function useAsyncRenderers(columnsConfig, item) {
7
7
 
8
8
  useEffect(() => {
9
9
  const asyncConfigs = columnsConfig.filter(config =>
10
- config.renderer && typeof config.renderer === 'function'
10
+ config.isAsync && config.renderer && typeof config.renderer === 'function'
11
11
  );
12
12
 
13
13
  if (asyncConfigs.length === 0) {
@@ -8,7 +8,7 @@ import _ from 'lodash';
8
8
  export default function withSecondaryData(WrappedComponent) {
9
9
  return (props) => {
10
10
 
11
- if (props.secondaryDisableWithData) {
11
+ if (props.secondaryDisableWithData || props.secondaryAlreadyHasWithData) {
12
12
  return <WrappedComponent {...props} />;
13
13
  }
14
14
 
@@ -104,6 +104,7 @@ export default function withSecondaryData(WrappedComponent) {
104
104
  return <WrappedComponent
105
105
  {...propsToPass}
106
106
  secondaryDisableWithData={false}
107
+ secondaryAlreadyHasWithData={true}
107
108
  SecondaryRepository={LocalSecondaryRepository}
108
109
  secondaryModel={secondaryModel}
109
110
  secondaryData={secondaryData}
@@ -24,7 +24,7 @@ import _ from 'lodash';
24
24
  export default function withSecondaryEditor(WrappedComponent, isTree = false) {
25
25
  return forwardRef((props, ref) => {
26
26
 
27
- if (props.secondaryDisableWithEditor) {
27
+ if (props.secondaryDisableWithEditor || props.secondaryAlreadyHasWithEditor) {
28
28
  return <WrappedComponent {...props} ref={ref} isTree={isTree} />;
29
29
  }
30
30
 
@@ -643,8 +643,9 @@ export default function withSecondaryEditor(WrappedComponent, isTree = false) {
643
643
 
644
644
  return <WrappedComponent
645
645
  {...props}
646
- ref={ref}
647
646
  secondaryDisableWithEditor={false}
647
+ secondaryAlreadyHasWithEditor={true}
648
+ ref={ref}
648
649
  secondaryCurrentRecord={secondaryCurrentRecord}
649
650
  secondarySetCurrentRecord={secondarySetCurrentRecord}
650
651
  secondaryIsEditorShown={secondaryIsEditorShown}