@onehat/ui 0.4.99 → 0.4.101

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.99",
3
+ "version": "0.4.101",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -201,6 +201,7 @@ function GridComponent(props) {
201
201
  },
202
202
  dragPreviewOptions, // optional object for drag preview positioning options
203
203
  areRowsDragSource = false,
204
+ areRowsDragFromHandleOnly,
204
205
  rowDragSourceType,
205
206
  getRowDragSourceItem,
206
207
  areRowsDropTarget = false,
@@ -641,10 +642,23 @@ function GridComponent(props) {
641
642
 
642
643
  const userHasPermissionToDrag = (!canUser || canUser(EDIT));
643
644
  if (userHasPermissionToDrag) {
645
+
646
+ // Determine whether dragging should only be allowed from a handle, based on global default and grid prop override
647
+ let dragFromRowHandleOnly = true;
648
+ if (!_.isNil(UiGlobals.gridAreRowsDragFromHandleOnly)) {
649
+ // allow global default
650
+ dragFromRowHandleOnly = UiGlobals.gridAreRowsDragFromHandleOnly;
651
+ }
652
+ if (!_.isNil(areRowsDragFromHandleOnly)) {
653
+ // allow grid props override
654
+ dragFromRowHandleOnly = areRowsDragFromHandleOnly;
655
+ }
656
+
644
657
  // assign event handlers
645
658
  if (canRowsReorder && isReorderMode) {
646
659
  WhichRow = DragSourceGridRow;
647
660
  rowReorderProps.isDragSource = true;
661
+ rowReorderProps.isDragFromHandleOnly = dragFromRowHandleOnly;
648
662
  rowReorderProps.dragSourceType = 'row';
649
663
  const dragIx = showHeaders ? index - 1 : index;
650
664
  rowReorderProps.dragSourceItem = {
@@ -656,6 +670,14 @@ function GridComponent(props) {
656
670
  onRowReorderDrag(dragState, dragIx);
657
671
  },
658
672
  };
673
+ // Add custom drag preview options
674
+ if (dragPreviewOptions) {
675
+ rowReorderProps.dragPreviewOptions = dragPreviewOptions;
676
+ }
677
+ // Add drag preview rendering
678
+ rowReorderProps.getDragProxy = getCustomDragProxy ?
679
+ (dragItem) => getCustomDragProxy(item, getSelection()) :
680
+ null; // Let GlobalDragProxy handle the default case
659
681
  rowReorderProps.onDragEnd = onRowReorderEnd;
660
682
  rowCanDrag = true;
661
683
  } else {
@@ -664,6 +686,7 @@ function GridComponent(props) {
664
686
  WhichRow = DragSourceGridRow;
665
687
  rowDragProps.isDragSource = true;
666
688
  rowDragProps.dragSourceType = rowDragSourceType;
689
+ rowDragProps.isDragFromHandleOnly = dragFromRowHandleOnly;
667
690
  if (getRowDragSourceItem) {
668
691
  rowDragProps.dragSourceItem = getRowDragSourceItem(item, getSelection, isInSelection, rowDragSourceType);
669
692
  // Ensure all drag items have a component reference
@@ -53,6 +53,7 @@ const GridRow = forwardRef((props, ref) => {
53
53
  isInlineEditorShown,
54
54
  isDraggable = false, // withDraggable
55
55
  isDragSource = false, // withDnd
56
+ isDragFromHandleOnly = true,
56
57
  isOver = false, // drop target
57
58
  canDrop,
58
59
  draggedItem,
@@ -124,7 +125,22 @@ const GridRow = forwardRef((props, ref) => {
124
125
  }
125
126
  const
126
127
  visibleColumns = _.filter(columnsConfig, (config) => !config.isHidden),
127
- isOnlyOneVisibleColumn = visibleColumns.length === 1;
128
+ isOnlyOneVisibleColumn = visibleColumns.length === 1,
129
+ rowShouldHaveDragRef = !isDragFromHandleOnly && (isDragSource || isDraggable) && !!dragSourceRef;
130
+ const setRowRef = (node) => {
131
+ if (typeof ref === 'function') {
132
+ ref(node);
133
+ } else if (ref) {
134
+ ref.current = node;
135
+ }
136
+ if (rowShouldHaveDragRef) {
137
+ if (typeof dragSourceRef === 'function') {
138
+ dragSourceRef(node);
139
+ } else if (dragSourceRef) {
140
+ dragSourceRef.current = node;
141
+ }
142
+ }
143
+ };
128
144
 
129
145
  const renderColumns = (item) => {
130
146
  if (_.isArray(columnsConfig)) {
@@ -136,7 +152,7 @@ const GridRow = forwardRef((props, ref) => {
136
152
  const
137
153
  propsToPass = columnProps[key] || {},
138
154
  colStyle = {},
139
- whichCursor = showRowHandle ? 'cursor-text' : 'cursor-pointer'; // when using rowSelectHandle, indicate that the row text is selectable, otherwise indicate that the row itself is selectable
155
+ whichCursor = showRowHandle && isDragFromHandleOnly ? 'cursor-text' : 'cursor-pointer'; // when using rowSelectHandle, indicate that the row text is selectable, otherwise indicate that the row itself is selectable
140
156
  let colClassName = clsx(
141
157
  'GridRow-column',
142
158
  'p-1',
@@ -144,6 +160,7 @@ const GridRow = forwardRef((props, ref) => {
144
160
  'border-r-black-100',
145
161
  'block',
146
162
  areCellsScrollable ? 'overflow-auto' : 'overflow-hidden',
163
+ isDragFromHandleOnly ? null : 'select-none',
147
164
  whichCursor,
148
165
  styles.GRID_ROW_MAX_HEIGHT_EXTRA,
149
166
  );
@@ -395,7 +412,7 @@ const GridRow = forwardRef((props, ref) => {
395
412
  let rowContents = <>
396
413
  {showRowHandle &&
397
414
  <RowHandle
398
- ref={dragSourceRef}
415
+ ref={isDragFromHandleOnly ? dragSourceRef : undefined}
399
416
  isDragSource={isDragSource}
400
417
  isDraggable={isDraggable}
401
418
  canSelect={rowCanSelect}
@@ -448,6 +465,7 @@ const GridRow = forwardRef((props, ref) => {
448
465
  let rowClassName = clsx(
449
466
  'GridRow-HStackNative',
450
467
  'items-center',
468
+ isDragFromHandleOnly ? null : 'select-none',
451
469
  );
452
470
  if (isOnlyOneVisibleColumn) {
453
471
  rowClassName += ' w-full';
@@ -459,7 +477,7 @@ const GridRow = forwardRef((props, ref) => {
459
477
  rowClassName += ' border-4 border-[#0ff]';
460
478
  }
461
479
  let row = <HStackNative
462
- ref={ref}
480
+ ref={rowShouldHaveDragRef ? setRowRef : ref}
463
481
  {...testProps('Row ' + (isSelected ? 'row-selected' : ''))}
464
482
  {...rowProps}
465
483
  key={hash}
@@ -498,6 +516,10 @@ const GridRow = forwardRef((props, ref) => {
498
516
  showRowHandle,
499
517
  rowCanSelect,
500
518
  rowCanDrag,
519
+ isDragFromHandleOnly,
520
+ isDragSource,
521
+ isDraggable,
522
+ dragSourceRef,
501
523
  ]);
502
524
  });
503
525
 
@@ -52,6 +52,21 @@ export default function withComponent(WrappedComponent) {
52
52
  parent,
53
53
  reference,
54
54
  path: reference ? (parent?.path || '' ) + '/' + reference : null,
55
+ waitForChild: (childReference, timeout = 5000) => {
56
+ return new Promise((resolve, reject) => {
57
+ const start = Date.now();
58
+ const checkForChild = () => {
59
+ if (typeof childrenRef.current[childReference] !== 'undefined') {
60
+ resolve(childrenRef.current[childReference]);
61
+ } else if (Date.now() - start > timeout) {
62
+ reject(new Error(`Timeout waiting for child: ${childReference}`));
63
+ } else {
64
+ setTimeout(checkForChild, 50);
65
+ }
66
+ };
67
+ checkForChild();
68
+ });
69
+ },
55
70
  hasChild: (childRef) => {
56
71
  const {
57
72
  reference,
@@ -222,15 +222,18 @@ export function GlobalDragProxy() {
222
222
  const {
223
223
  isDragging,
224
224
  item,
225
- currentOffset,
225
+ clientOffset,
226
+ sourceClientOffset,
226
227
  } = useDragLayer((monitor) => {
227
228
  return {
228
229
  isDragging: monitor.isDragging(),
229
230
  item: monitor.getItem(),
230
- currentOffset: monitor.getSourceClientOffset(),
231
+ clientOffset: monitor.getClientOffset(),
232
+ sourceClientOffset: monitor.getSourceClientOffset(),
231
233
  };
232
234
  });
233
235
 
236
+ const currentOffset = clientOffset || sourceClientOffset;
234
237
  if (!isDragging || !currentOffset || CURRENT_MODE !== UI_MODE_WEB) { // Native uses a native drag layer, so we don't need to render a custom proxy
235
238
  return null;
236
239
  }
package/src/UiGlobals.js CHANGED
@@ -13,6 +13,7 @@ const Globals = {
13
13
  doubleClickingGridRowOpensEditorInViewMode: false,
14
14
  disableSavedColumnsConfig: true,
15
15
  autoSubmitDelay: 500,
16
+ // gridAreRowsDragFromHandleOnly: true,
16
17
  // stayInEditModeOnSelectionChange: true,
17
18
  // isSideEditorAlwaysEditMode: true,
18
19