@onehat/ui 0.4.98 → 0.4.99

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.98",
3
+ "version": "0.4.99",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -208,6 +208,7 @@ function GridComponent(props) {
208
208
  onRowDrop,
209
209
  onDragStart,
210
210
  onDragEnd,
211
+ rowLongPressDelayMs,
211
212
 
212
213
  // withComponent
213
214
  self,
@@ -300,6 +301,7 @@ function GridComponent(props) {
300
301
  [localColumnsConfig, setLocalColumnsConfigRaw] = useState([]),
301
302
  [isReorderMode, setIsReorderMode] = useState(false),
302
303
  showRowHandle = showSelectHandle || areRowsDragSource || (canRowsReorder && isReorderMode),
304
+ rowLongPressDelay = rowLongPressDelayMs ?? ((areRowsDragSource || canRowsReorder) ? 800 : undefined),
303
305
  [lastMeasuredContainerHeight, setLastMeasuredContainerHeight] = useState(0),
304
306
  getMeasurementPhase = () => {
305
307
  return measurementPhaseRaw.current;
@@ -469,11 +471,12 @@ function GridComponent(props) {
469
471
  <Pressable
470
472
  dataSet={{ ix: index }}
471
473
  {...testProps(getRowTestId ? getRowTestId(row) : ((Repository ? Repository.schema.name : 'GridRow') + '-' + item?.id))}
474
+ delayLongPress={rowLongPressDelay}
472
475
  onPress={(e) => {
473
476
  if (e.preventDefault && e.cancelable) {
474
477
  e.preventDefault();
475
478
  }
476
- if (isHeaderRow || isReorderMode) {
479
+ if (isHeaderRow) {
477
480
  return
478
481
  }
479
482
  if (CURRENT_MODE === UI_MODE_WEB) {
@@ -485,6 +488,9 @@ function GridComponent(props) {
485
488
  }
486
489
  break;
487
490
  case DOUBLE_CLICK:
491
+ if (isReorderMode) {
492
+ return; // don't allow double-clicks while in reorder mode
493
+ }
488
494
  if (editorType === EDITOR_TYPE__SIDE) {
489
495
  // For side-editors, a double-click just acts like a single click
490
496
  if (!getIsEditorShown()) {
@@ -929,26 +935,58 @@ function GridComponent(props) {
929
935
  onRowReorderEnd = (item, monitor) => {
930
936
  const
931
937
  { ix: dropIx, useBottom, marker, rows, dragIx } = cachedDragElements.current,
932
- shouldMove = dropIx !== dragIx;
933
- if (shouldMove && dropIx !== -1) {
934
- // Update the row with the new ix
935
- let dragRecord,
936
- dropRecord;
938
+ selectionList = item?.getSelection ? item.getSelection() : (dragSelectionRef.current || selection || []);
939
+ if (dropIx === -1) {
940
+ marker.remove();
941
+ cachedDragElements.current = null;
942
+ return;
943
+ }
944
+
945
+ const
946
+ // normalize the current selection to ids
947
+ itemsList = Repository ? entities : data,
948
+ dragItem = Repository ? Repository.getByIx(dragIx) : itemsList?.[dragIx],
949
+ selectionIds = _.compact(_.map(selectionList, (selectedItem) => {
950
+ if (!selectedItem) {
951
+ return null;
952
+ }
953
+ if (_.isObject(selectedItem)) {
954
+ return Repository ? selectedItem.id : selectedItem[idIx];
955
+ }
956
+ return selectedItem;
957
+ })),
958
+ // decide if we're moving the selected items or just the dragged item
959
+ dragItemId = dragItem ? (Repository ? dragItem.id : dragItem[idIx]) : null,
960
+ useSelection = !!(dragItemId && selectionIds.includes(dragItemId)),
961
+ dragItems = useSelection ? selectionIds : (dragItemId ? [dragItemId] : []),
962
+ // get the indices of the selected items
963
+ selectedIndicesRaw = Repository
964
+ ? _.map(dragItems, (id) => itemsList?.findIndex((item) => item?.id === id))
965
+ : _.map(dragItems, (id) => itemsList?.findIndex((item) => item?.[idIx] === id)),
966
+ selectedIndices = _.uniq(_.filter(selectedIndicesRaw, (ix) => ix > -1)).sort((a, b) => a - b),
967
+ selectedIndicesSet = new Set(selectedIndices),
968
+ insertionIndexOriginal = useBottom ? dropIx + 1 : dropIx,
969
+ // get the drop record
970
+ dropRecord = Repository ? Repository.getByIx(dropIx) : itemsList?.[dropIx],
971
+ dropRecordId = dropRecord ? (Repository ? dropRecord.id : dropRecord[idIx]) : null,
972
+ // decide if we should move
973
+ shouldMove = !dropRecordId || !selectionIds.includes(dropRecordId);
974
+
975
+ if (shouldMove && selectedIndices.length) {
937
976
  if (Repository) {
938
977
  if (!Repository.isDestroyed) {
939
- dragRecord = Repository.getByIx(dragIx);
940
- dropRecord = Repository.getByIx(dropIx);
941
- if (dropRecord) {
942
- Repository.reorder(dragRecord, dropRecord, useBottom ? DROP_POSITION_AFTER : DROP_POSITION_BEFORE);
978
+ if (dropRecord && dragItems.length) {
979
+ Repository.reorder(dragItems, dropRecord, useBottom ? DROP_POSITION_AFTER : DROP_POSITION_BEFORE);
943
980
  }
944
981
  }
945
- } else {
946
- function arrayMove(arr, fromIndex, toIndex) {
947
- var element = arr[fromIndex];
948
- arr.splice(fromIndex, 1);
949
- arr.splice(toIndex, 0, element);
950
- }
951
- arrayMove(data, compensatedDragIx, finalDropIx);
982
+ } else if (itemsList && itemsList.length) {
983
+ const
984
+ removedBefore = _.filter(selectedIndices, (ix) => ix < insertionIndexOriginal).length,
985
+ insertionIndex = insertionIndexOriginal - removedBefore,
986
+ selectedItems = _.map(selectedIndices, (ix) => itemsList[ix]),
987
+ remainingItems = _.filter(itemsList, (entry, ix) => !selectedIndicesSet.has(ix));
988
+ remainingItems.splice(insertionIndex, 0, ...selectedItems);
989
+ itemsList.splice(0, itemsList.length, ...remainingItems);
952
990
  }
953
991
  }
954
992
 
@@ -110,6 +110,7 @@ function TreeComponent(props) {
110
110
  showHeaderToolbar = true,
111
111
  showHovers = true,
112
112
  showSelectHandle = true,
113
+ nodeLongPressDelayMs,
113
114
  isNodeSelectable = true,
114
115
  isNodeHoverable = true,
115
116
  allowToggleSelection = true, // i.e. single click with no shift key toggles the selection of the node clicked on
@@ -219,6 +220,7 @@ function TreeComponent(props) {
219
220
  [highlitedDatum, setHighlitedDatum] = useState(null),
220
221
  [treeSearchValue, setTreeSearchValue] = useState(''),
221
222
  showNodeHandle = showSelectHandle || areNodesDragSource,
223
+ nodeLongPressDelay = nodeLongPressDelayMs ?? ((areNodesDragSource || canNodesMoveInternally) ? 800 : undefined),
222
224
  // state getters & setters
223
225
  getTreeNodeData = () => {
224
226
  return treeNodeData.current;
@@ -1092,6 +1094,7 @@ function TreeComponent(props) {
1092
1094
  return <Pressable
1093
1095
  {...testProps((Repository ? Repository.schema.name : 'TreeNode') + '-' + item?.id)}
1094
1096
  key={item.hash}
1097
+ delayLongPress={nodeLongPressDelay}
1095
1098
  onPress={(e) => {
1096
1099
  if (e.preventDefault && e.cancelable) {
1097
1100
  e.preventDefault();