pixel-react 1.13.93 → 1.13.95

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 (47) hide show
  1. package/lib/_virtual/index4.js +3 -5
  2. package/lib/_virtual/index4.js.map +1 -1
  3. package/lib/_virtual/index5.js +5 -3
  4. package/lib/_virtual/index5.js.map +1 -1
  5. package/lib/components/AttachmentButton/AttachmentButton.js +1 -1
  6. package/lib/components/EditLabel/EditLabel.js +1 -1
  7. package/lib/components/EditLabel/EditLabel.js.map +1 -1
  8. package/lib/components/Excel/ExcelFile/ExcelFileComponents/ActiveCell.js +29 -20
  9. package/lib/components/Excel/ExcelFile/ExcelFileComponents/ActiveCell.js.map +1 -1
  10. package/lib/components/Excel/ExcelFile/ExcelFileComponents/Cell.d.ts +1 -1
  11. package/lib/components/Excel/ExcelFile/ExcelFileComponents/Cell.js +8 -9
  12. package/lib/components/Excel/ExcelFile/ExcelFileComponents/Cell.js.map +1 -1
  13. package/lib/components/Excel/ExcelFile/ExcelFileComponents/DataViewer.js +3 -3
  14. package/lib/components/Excel/ExcelFile/ExcelFileComponents/DataViewer.js.map +1 -1
  15. package/lib/components/Excel/ExcelFile/ExcelFileComponents/Spreadsheet.js +3 -1
  16. package/lib/components/Excel/ExcelFile/ExcelFileComponents/Spreadsheet.js.map +1 -1
  17. package/lib/components/MachineInputField/MachineInputField.js +2 -1
  18. package/lib/components/MachineInputField/MachineInputField.js.map +1 -1
  19. package/lib/components/TableTreeFn/Components/TableBody.js +4 -16
  20. package/lib/components/TableTreeFn/Components/TableBody.js.map +1 -1
  21. package/lib/components/TableTreeFn/TableTreeFn.js +140 -128
  22. package/lib/components/TableTreeFn/TableTreeFn.js.map +1 -1
  23. package/lib/components/TableTreeFn/types.d.ts +1 -0
  24. package/lib/index.cjs +190 -179
  25. package/lib/index.cjs.map +1 -1
  26. package/lib/index.d.ts +1 -0
  27. package/lib/node_modules/input-format/modules/react/Input.js +1 -1
  28. package/lib/node_modules/js-beautify/js/src/css/beautifier.js +1 -1
  29. package/lib/node_modules/js-beautify/js/src/css/options.js +1 -1
  30. package/lib/node_modules/js-beautify/js/src/html/beautifier.js +1 -1
  31. package/lib/node_modules/js-beautify/js/src/html/options.js +1 -1
  32. package/lib/node_modules/js-beautify/js/src/javascript/beautifier.js +1 -1
  33. package/lib/node_modules/js-beautify/js/src/javascript/options.js +1 -1
  34. package/lib/node_modules/react-google-recaptcha/lib/esm/recaptcha.js +1 -1
  35. package/lib/node_modules/react-phone-number-input/modules/CountryIcon.js +1 -1
  36. package/lib/node_modules/react-phone-number-input/modules/CountrySelect.js +1 -1
  37. package/lib/node_modules/react-phone-number-input/modules/Flag.js +1 -1
  38. package/lib/node_modules/react-phone-number-input/modules/InputBasic.js +1 -1
  39. package/lib/node_modules/react-phone-number-input/modules/InputSmart.js +1 -1
  40. package/lib/node_modules/react-phone-number-input/modules/InternationalIcon.js +1 -1
  41. package/lib/node_modules/react-phone-number-input/modules/PhoneInputWithCountry.js +1 -1
  42. package/lib/node_modules/react-phone-number-input/modules/PhoneInputWithCountryDefault.js +1 -1
  43. package/lib/node_modules/react-phone-number-input/modules/PropTypes.js +1 -1
  44. package/lib/node_modules/use-context-selector/dist/index.js +1 -1
  45. package/lib/styles.css +1 -1
  46. package/lib/styles.css.map +1 -1
  47. package/package.json +1 -1
package/lib/index.cjs CHANGED
@@ -16977,7 +16977,7 @@ const EditLabel = ({
16977
16977
  })]
16978
16978
  })]
16979
16979
  }) : jsxRuntime.jsx(Tooltip, {
16980
- title: getTooltipTitle(),
16980
+ title: isTextTruncated(text, truncatedTextCount, truncatedType) ? getTooltipTitle() : '',
16981
16981
  placement: tooltip?.tooltipPlacement ?? 'bottom',
16982
16982
  children: jsxRuntime.jsx("span", {
16983
16983
  className: 'ff-add-module-display-text',
@@ -35097,7 +35097,8 @@ const MachineInputField = ({
35097
35097
  edge: 'edge',
35098
35098
  firefox: 'fire_fox',
35099
35099
  chrome: 'chrome_icon',
35100
- explorer: 'internet_explorer'
35100
+ explorer: 'internet_explorer',
35101
+ ios: 'mac_icon'
35101
35102
  };
35102
35103
  const isManualScript = scriptType.toLowerCase() === 'manual';
35103
35104
  return jsxRuntime.jsxs("div", {
@@ -35769,7 +35770,7 @@ const AttachmentButton = ({
35769
35770
  if (fileInputRef.current?.files) {
35770
35771
  const files = Array.from(fileInputRef.current.files);
35771
35772
  if (files.length > 5) {
35772
- setFileError('Maximun file(s) can be uploaded: 5');
35773
+ setFileError('Maximum file(s) can be uploaded: 5');
35773
35774
  fileInputRef.current.value = '';
35774
35775
  return;
35775
35776
  }
@@ -41037,7 +41038,6 @@ const Cell = ({
41037
41038
  row,
41038
41039
  column,
41039
41040
  DataViewer,
41040
- selected,
41041
41041
  active,
41042
41042
  dragging,
41043
41043
  mode,
@@ -41071,13 +41071,15 @@ const Cell = ({
41071
41071
  }, [setCellDimensions, select, dragging, point]);
41072
41072
  React__namespace.useEffect(() => {
41073
41073
  const root = rootRef.current;
41074
- if (selected && root) {
41074
+ if (!root) return;
41075
+ const updateDimensions = () => {
41075
41076
  setCellDimensions(point, getOffsetRect(root));
41076
- }
41077
- if (root && active && mode === 'view') {
41078
- root.focus();
41079
- }
41080
- }, [setCellDimensions, selected, active, mode, point, data]);
41077
+ };
41078
+ updateDimensions();
41079
+ const observer = new ResizeObserver(updateDimensions);
41080
+ observer.observe(root);
41081
+ return () => observer.disconnect();
41082
+ }, [setCellDimensions, point]);
41081
41083
  if (data && data.DataViewer) {
41082
41084
  DataViewer = data.DataViewer;
41083
41085
  }
@@ -41120,12 +41122,10 @@ const enhance = CellComponent => {
41120
41122
  const mode = useSelector(state => active ? state.mode : 'view');
41121
41123
  const data = useSelector(state => get$1(point, state.model.data));
41122
41124
  const evaluatedData = useSelector(state => get$1(point, state.model.evaluatedData));
41123
- const selected = useSelector(state => state.selected.has(state.model.data, point));
41124
41125
  const dragging = useSelector(state => state.dragging);
41125
41126
  const copied = useSelector(state => state.copied?.has(point) || false);
41126
41127
  return jsxRuntime.jsx(CellComponent, {
41127
41128
  ...props,
41128
- selected: selected,
41129
41129
  active: active,
41130
41130
  copied: copied,
41131
41131
  dragging: dragging,
@@ -41154,10 +41154,10 @@ const DataViewer = ({
41154
41154
  return jsxRuntime.jsx(jsxRuntime.Fragment, {});
41155
41155
  }
41156
41156
  const fileList = JSON.parse(value);
41157
- return fileList.map((file, index) => {
41158
- return jsxRuntime.jsxs("div", {
41157
+ return fileList.map(file => {
41158
+ return jsxRuntime.jsx("div", {
41159
41159
  className: "ff-spreadsheet-data-viewer--fileType",
41160
- children: [index + 1, ". ", file.name]
41160
+ children: file.name.split('*')[0]
41161
41161
  }, file.name);
41162
41162
  });
41163
41163
  };
@@ -41315,9 +41315,6 @@ const ActiveCell = props => {
41315
41315
  const fileLength = selectedFiles?.length + uniqueFiles?.length;
41316
41316
  const extractHeight = fileLength > 0 ? fileLength * 25 : 1;
41317
41317
  const processedFiles = [...existingFiles];
41318
- if (duplicateCount > 0) {
41319
- toast.info('Duplicate attachments not allowed within the same row');
41320
- }
41321
41318
  const uploadPromises = uniqueFiles?.map(async file => {
41322
41319
  try {
41323
41320
  if (file.name.includes('*')) {
@@ -41439,7 +41436,7 @@ const ActiveCell = props => {
41439
41436
  inputType: cell?.inputType
41440
41437
  });
41441
41438
  dispatch(setRowHeight(active?.row || 0, extractHeight));
41442
- setSelectedFiles(processedFiles.map(file => new File([new Blob()], file.name)));
41439
+ setSelectedFiles(processedFiles.map(file => new File([new Blob()], file.name?.split('*')[0] ?? 'default')));
41443
41440
  }
41444
41441
  if (memoryFullCount > 0) {
41445
41442
  toast.info('No memory available to add the file');
@@ -41454,8 +41451,6 @@ const ActiveCell = props => {
41454
41451
  console.error('Upload operation failed:', error);
41455
41452
  toast.error('Operation failed');
41456
41453
  }
41457
- } else if (duplicateCount > 0) {
41458
- toast.info('Duplicate attachments not allowed within the same row');
41459
41454
  }
41460
41455
  } else if (actionType === 'DELETE' && cell?.inputType?.type === 'file') {
41461
41456
  try {
@@ -41497,7 +41492,7 @@ const ActiveCell = props => {
41497
41492
  style: cell?.style,
41498
41493
  inputType: cell?.inputType
41499
41494
  });
41500
- setSelectedFiles(updatedFileDetails?.map(file => new File([new Blob()], file.name)));
41495
+ setSelectedFiles(updatedFileDetails?.map(file => new File([new Blob()], file.name.split('*')[0])));
41501
41496
  toast.success(`${deletedCount} file${deletedCount > 1 ? 's' : ''} deleted successfully`);
41502
41497
  } else if (selected?.length) {
41503
41498
  const validFiles = updatedFileDetails?.filter(file => file.id && file.name);
@@ -41509,7 +41504,7 @@ const ActiveCell = props => {
41509
41504
  style: cell?.style,
41510
41505
  inputType: cell?.inputType
41511
41506
  });
41512
- setSelectedFiles(validFiles.map(file => new File([new Blob()], file.name)));
41507
+ setSelectedFiles(validFiles.map(file => new File([new Blob()], file.name.split('*')[0])));
41513
41508
  toast.error('Failed to delete file(s). Invalid file data detected.');
41514
41509
  } else {
41515
41510
  toast.error('Failed to delete file(s). No valid files removed.');
@@ -41526,13 +41521,24 @@ const ActiveCell = props => {
41526
41521
  }
41527
41522
  };
41528
41523
  const handleClick = e => {
41529
- const selectedList = e.target.innerText;
41530
- if (selectedList) {
41531
- JSON.parse(cell?.value).map(file => {
41532
- if (file.name === selectedList && props.attachmentAction?.viewAttachment) {
41533
- props.attachmentAction?.viewAttachment(file.id, file.name);
41534
- }
41535
- });
41524
+ const fileElement = e.target.closest('.ff-attachment-files');
41525
+ const isIconClick = e.target.closest('.ff-icon-container, .ff-icon-click, .ff-icon-danger');
41526
+ if (!fileElement || isIconClick || !cell?.value || !props.attachmentAction?.viewAttachment) {
41527
+ console.warn('Missing file element, icon click, cell value, or viewAttachment action');
41528
+ return;
41529
+ }
41530
+ try {
41531
+ const files = JSON.parse(cell.value);
41532
+ const fileElements = fileElement.parentElement?.querySelectorAll('.ff-attachment-files') || [];
41533
+ const fileIndex = Array.from(fileElements).indexOf(fileElement);
41534
+ if (fileIndex === -1 || !files[fileIndex]) {
41535
+ console.error('File index not found or invalid');
41536
+ return;
41537
+ }
41538
+ const file = files[fileIndex];
41539
+ props.attachmentAction.viewAttachment(file.id, file.name?.split('*')[0] ?? 'default');
41540
+ } catch (error) {
41541
+ console.error('Error parsing cell value:', error);
41536
41542
  }
41537
41543
  };
41538
41544
  React__namespace.useEffect(() => {
@@ -41540,11 +41546,13 @@ const ActiveCell = props => {
41540
41546
  if (!hidden && root) {
41541
41547
  root.focus();
41542
41548
  if (cell?.inputType?.type === 'file' && cell?.value) {
41543
- const parsedFiles = JSON.parse(cell.value).map(file => {
41544
- const blob = new Blob([]);
41545
- return new File([blob], file.name);
41546
- });
41547
- setSelectedFiles(parsedFiles);
41549
+ try {
41550
+ const parsedFiles = JSON.parse(cell.value).map(file => new File([new Blob()], file.name.split('*')[0] ?? 'default'));
41551
+ setSelectedFiles(parsedFiles);
41552
+ } catch (error) {
41553
+ console.error('Error parsing cell value for files:', error);
41554
+ setSelectedFiles([]);
41555
+ }
41548
41556
  } else {
41549
41557
  setSelectedFiles([]);
41550
41558
  }
@@ -41651,6 +41659,7 @@ const ActiveCell = props => {
41651
41659
  buttonLabel: "+ Attachments",
41652
41660
  buttonVariant: "tertiary",
41653
41661
  deleteButton: true,
41662
+ selectedFileMessage: 'Duplicate attachments not allowed within the same row',
41654
41663
  addAttachmentButton: true,
41655
41664
  isInfoIconRequired: false,
41656
41665
  truncateMaxLimit: dimensions.width - 60
@@ -42260,7 +42269,9 @@ const Spreadsheet = props => {
42260
42269
  clientHeight
42261
42270
  } = target;
42262
42271
  setMaxHeight(Math.min(rootRef.current.clientHeight, clientHeight));
42263
- showHider && setMaxWidth(Math.min(rootRef.current.clientWidth, clientWidth));
42272
+ if (showHider) {
42273
+ setMaxWidth(Math.min(rootRef.current.clientWidth, clientWidth));
42274
+ }
42264
42275
  }
42265
42276
  }
42266
42277
  });
@@ -47047,15 +47058,9 @@ const TableBody = ({
47047
47058
  // if (checkEmpty(flattenedTreeData)) {
47048
47059
  // return null;
47049
47060
  // }
47050
- return jsxRuntime.jsxs("tbody", {
47061
+ return jsxRuntime.jsx("tbody", {
47051
47062
  className: "ff-table-tree-body",
47052
- children: [jsxRuntime.jsx("div", {
47053
- style: {
47054
- position: 'sticky',
47055
- left: 0
47056
- },
47057
- id: "ff-table-tree-first-node"
47058
- }), addNewRow(flattenedTreeData, newNode ?? {}, rootNode)?.map((node, index) => !node?.hide ? jsxRuntime.jsx(TableRow, {
47063
+ children: addNewRow(flattenedTreeData, newNode ?? {}, rootNode)?.map((node, index) => !node?.hide ? jsxRuntime.jsx(TableRow, {
47059
47064
  node: node,
47060
47065
  columnsData: columnsData,
47061
47066
  selected: selected,
@@ -47074,13 +47079,7 @@ const TableBody = ({
47074
47079
  addModuleInputWidth: addModuleInputWidth,
47075
47080
  addModuleSelectWidth: addModuleSelectWidth,
47076
47081
  disableEditLabelConfirmIcon: disableEditLabelConfirmIcon
47077
- }, node.key) : null), jsxRuntime.jsx("div", {
47078
- style: {
47079
- position: 'sticky',
47080
- left: 0
47081
- },
47082
- id: "ff-table-tree-last-node"
47083
- })]
47082
+ }, node.key) : null)
47084
47083
  });
47085
47084
  };
47086
47085
 
@@ -47101,7 +47100,6 @@ const TableTreeFn = /*#__PURE__*/React.forwardRef(({
47101
47100
  handleEditFieldError,
47102
47101
  loading = false,
47103
47102
  rootNode,
47104
- getContentLength,
47105
47103
  pagination = true,
47106
47104
  selectedNode,
47107
47105
  tableHeaderBgColor = 'var(--border-color)',
@@ -47113,130 +47111,167 @@ const TableTreeFn = /*#__PURE__*/React.forwardRef(({
47113
47111
  onScroll,
47114
47112
  disableEditLabelConfirmIcon = false,
47115
47113
  transparentHeader = false,
47116
- navigateTreeNode = null
47114
+ navigateTreeNode = null,
47115
+ handleRemoveNavigateTreeNode = () => {}
47117
47116
  }, ref) => {
47118
47117
  const [expanding, setExpanding] = React.useState(null);
47119
- const [isLoading, setIsLoading] = React.useState(null);
47120
- const observerRef = React.useRef(null);
47121
- const containerRef = React.useRef(null); // Reference for scroll container
47118
+ const [scrollDirection, setScrollDirection] = React.useState(null); // this state will help to idenetify the direction during the pagination api call
47122
47119
  const [prevScrollTop, setPrevScrollTop] = React.useState(null);
47120
+ const [prevScrollHeight, setPrevScrollHeight] = React.useState(null);
47121
+ const [maintainScrollPosition, setMaintainScrollPosition] = React.useState(null);
47122
+ const containerRef = React.useRef(null);
47123
47123
  const previousTreeDataRef = React.useRef([]);
47124
- //new loadMoreAbove function
47125
- const loadMoreAbove = () => {
47126
- if (loading || isLoading === 'above') return;
47127
- console.log('calling above');
47128
- setIsLoading('above');
47124
+ const scrollPositionRef = React.useRef({
47125
+ lastScrollTop: 0,
47126
+ lastScrollTime: 0,
47127
+ direction: null
47128
+ });
47129
+ const scrollDebounceRef = React.useRef(null);
47130
+ // this is the Distance from edge to trigger the scroll below and above
47131
+ const scrollThreshold = 128;
47132
+ // this is loadMore functions which will the trigger the pagination apis in platform
47133
+ const loadMoreAbove = React.useCallback(() => {
47134
+ if (loading || scrollDirection === 'above') return;
47135
+ setScrollDirection('above');
47129
47136
  setPrevScrollTop(containerRef.current?.scrollTop ?? null);
47137
+ setPrevScrollHeight(containerRef.current?.scrollHeight ?? null);
47130
47138
  loadMore('above');
47131
- };
47132
- const loadMoreBelow = () => {
47133
- if (loading || isLoading === 'below') return;
47134
- console.log('calling below');
47135
- setIsLoading('below');
47136
- // Trigger the loadMore callback for data loading from below
47139
+ }, [loading, scrollDirection, loadMore]);
47140
+ const loadMoreBelow = React.useCallback(() => {
47141
+ if (loading || scrollDirection === 'below') return;
47142
+ setScrollDirection('below');
47137
47143
  loadMore('below');
47138
- };
47139
- //new handle Scroll function
47144
+ }, [loading, scrollDirection, loadMore]);
47145
+ // this is scroll handler
47140
47146
  const handleScroll = React.useCallback(() => {
47141
47147
  const container = containerRef.current;
47142
- const previousTreeData = previousTreeDataRef.current;
47143
- if (!loading && container && isLoading === 'above' && previousTreeData.length > 0 && prevScrollTop !== null) {
47144
- let addedRowsCount = 0;
47145
- if (getContentLength) {
47146
- addedRowsCount = getContentLength;
47147
- } else {
47148
- for (let i = 0; i < treeData.length; i++) {
47149
- if (previousTreeData[0] === treeData[i]) break;
47150
- addedRowsCount++;
47151
- }
47148
+ if (!container) return;
47149
+ const now = Date.now();
47150
+ const currentScrollTop = container.scrollTop;
47151
+ const scrollHeight = container.scrollHeight;
47152
+ const clientHeight = container.clientHeight;
47153
+ // Determine scroll direction
47154
+ const direction = currentScrollTop > scrollPositionRef.current.lastScrollTop ? 'down' : 'up';
47155
+ scrollPositionRef.current = {
47156
+ lastScrollTop: currentScrollTop,
47157
+ lastScrollTime: now,
47158
+ direction
47159
+ };
47160
+ // Clear any pending debounce
47161
+ if (scrollDebounceRef.current) {
47162
+ clearTimeout(scrollDebounceRef.current);
47163
+ }
47164
+ // Check if we're near the bottom (for loading more below)
47165
+ const nearBottom = scrollHeight - (currentScrollTop + clientHeight) < scrollThreshold;
47166
+ if (direction === 'down' && nearBottom && !loading && !scrollDirection && treeData[treeData.length - 1]?.lastResource !== true) {
47167
+ console.log('Loading more below');
47168
+ scrollDebounceRef.current = setTimeout(() => {
47169
+ loadMoreBelow();
47170
+ }, 150);
47171
+ }
47172
+ // Check if we're near the top (for loading more above)
47173
+ const nearTop = currentScrollTop < scrollThreshold;
47174
+ if (direction === 'up' && nearTop && !loading && !scrollDirection && treeData[0]?.lastResource !== true) {
47175
+ console.log('Loading more above');
47176
+ scrollDebounceRef.current = setTimeout(() => {
47177
+ loadMoreAbove();
47178
+ }, 150);
47179
+ }
47180
+ console.log('hanldeScroll called');
47181
+ // if (onScroll) {
47182
+ // onScroll();
47183
+ // }
47184
+ }, [loading, scrollDirection, treeData, loadMoreAbove, loadMoreBelow, onScroll]);
47185
+ // Attach scroll event listener for updated first node when we scroll
47186
+ React.useEffect(() => {
47187
+ const scrollDiv = containerRef.current;
47188
+ if (scrollDiv && onScroll) {
47189
+ scrollDiv.addEventListener('scroll', onScroll);
47190
+ }
47191
+ return () => {
47192
+ if (scrollDiv && onScroll) {
47193
+ scrollDiv.removeEventListener('scroll', onScroll);
47152
47194
  }
47153
- let retries = 0;
47154
- const maxRetries = 30;
47155
- const tryRestoreScroll = () => {
47156
- const allRows = Array.from(container.querySelectorAll('.ff-table-tree-row'));
47157
- // Total added height of new rows
47158
- let totalAddedHeight = 0;
47159
- for (let i = 0; i < addedRowsCount; i++) {
47160
- const height = allRows[i]?.getBoundingClientRect().height || 0;
47161
- totalAddedHeight += height;
47162
- }
47163
- const canScroll = container.scrollHeight > container.clientHeight;
47164
- const validHeights = totalAddedHeight > 0;
47165
- if (validHeights && canScroll) {
47166
- container.scrollTop = prevScrollTop + totalAddedHeight;
47167
- previousTreeDataRef.current = treeData;
47168
- } else if (retries < maxRetries) {
47169
- retries++;
47170
- requestAnimationFrame(tryRestoreScroll);
47171
- } else {
47172
- previousTreeDataRef.current = treeData;
47173
- console.warn('Failed to restore scroll position after max retries');
47174
- }
47175
- };
47176
- console.log(`Attempting to restore scroll position after loading more data. Added rows count: ${addedRowsCount}, retries: ${retries}`);
47177
- // Start scroll adjustment
47178
- requestAnimationFrame(tryRestoreScroll);
47195
+ };
47196
+ }, [onScroll]);
47197
+ React.useEffect(() => {
47198
+ return () => {
47199
+ if (scrollDebounceRef.current) {
47200
+ clearTimeout(scrollDebounceRef.current);
47201
+ }
47202
+ };
47203
+ }, []);
47204
+ // Handle scroll position restoration after loading
47205
+ React.useLayoutEffect(() => {
47206
+ if (!loading && scrollDirection === 'above' && prevScrollTop !== null && prevScrollHeight !== null) {
47207
+ const container = containerRef.current;
47208
+ if (!container) return;
47209
+ const scrollHeightDiff = container.scrollHeight - prevScrollHeight;
47210
+ if (scrollHeightDiff > 0) {
47211
+ container.scrollTop = prevScrollTop + scrollHeightDiff;
47212
+ }
47213
+ setScrollDirection(null);
47214
+ setPrevScrollTop(null);
47215
+ setPrevScrollHeight(null);
47216
+ } else if (!loading) {
47217
+ setScrollDirection(null);
47179
47218
  }
47180
- }, [loading, isLoading, treeData, getContentLength, prevScrollTop]);
47219
+ }, [loading, scrollDirection, prevScrollTop, prevScrollHeight]);
47220
+ // Handle navigation to specific nodes
47181
47221
  React.useEffect(() => {
47182
- const scrollContainer = document.getElementById('ff-table-tree-scroll-container');
47183
- const lastNode = document.getElementById('ff-table-tree-last-node');
47184
- const firstNode = document.getElementById('ff-table-tree-first-node');
47185
- if (!scrollContainer || !lastNode || !firstNode || !treeData?.length || !pagination) return;
47186
- const isLastResourceBelow = !!treeData[treeData.length - 1]?.lastResource;
47187
- const isLastResourceAbove = !!treeData[0]?.lastResource;
47188
- // Clean up old observer before creating a new one
47189
- observerRef.current?.disconnect();
47190
- const observerCallback = entries => {
47191
- entries.forEach(entry => {
47192
- const nodeId = entry.target.id;
47193
- const direction = nodeId === 'ff-table-tree-last-node' ? 'below' : 'above';
47194
- console.log('entries', entry);
47195
- if (entry.isIntersecting) {
47196
- if (direction === 'below' && !isLastResourceBelow) {
47197
- console.log('LoadMoreBelow from observer');
47198
- loadMoreBelow();
47199
- } else if (direction === 'above' && !isLastResourceAbove) {
47200
- console.log('LoadMoreAbove from observer');
47201
- loadMoreAbove();
47202
- }
47203
- }
47204
- });
47222
+ if (navigateTreeNode) {
47223
+ const node = document.getElementById(navigateTreeNode);
47224
+ const container = containerRef.current;
47225
+ if (node && container) {
47226
+ // Store current scroll position
47227
+ setMaintainScrollPosition(container.scrollTop);
47228
+ // Calculate scroll position
47229
+ const nodeRect = node.getBoundingClientRect();
47230
+ const containerRect = container.getBoundingClientRect();
47231
+ const scrollTop = container.scrollTop;
47232
+ const nodeTop = nodeRect.top - containerRect.top + scrollTop;
47233
+ const containerHeight = containerRect.height;
47234
+ // Scroll to center the node
47235
+ container.scrollTo({
47236
+ top: nodeTop - containerHeight / 2 + nodeRect.height / 2,
47237
+ behavior: 'smooth'
47238
+ });
47239
+ }
47240
+ }
47241
+ return () => {
47242
+ handleRemoveNavigateTreeNode();
47205
47243
  };
47206
- observerRef.current = new IntersectionObserver(observerCallback, {
47207
- root: scrollContainer,
47208
- rootMargin: '30px',
47209
- threshold: 1
47210
- });
47211
- if (!isLastResourceBelow) observerRef.current.observe(lastNode);
47212
- if (!isLastResourceAbove) observerRef.current.observe(firstNode);
47213
- if (previousTreeDataRef.current.length === 0) {
47214
- previousTreeDataRef.current = treeData;
47244
+ }, [navigateTreeNode, treeData]);
47245
+ // Restore scroll position after navigation
47246
+ React.useEffect(() => {
47247
+ if (maintainScrollPosition !== null && !loading && containerRef.current) {
47248
+ containerRef.current.scrollTop = maintainScrollPosition;
47249
+ setMaintainScrollPosition(null);
47215
47250
  }
47251
+ }, [maintainScrollPosition, loading]);
47252
+ // Setup scroll listener
47253
+ React.useEffect(() => {
47254
+ const container = containerRef.current;
47255
+ if (!container || !pagination) return;
47256
+ container.addEventListener('scroll', handleScroll);
47257
+ // Initial check in case we're already at the bottom/top
47258
+ handleScroll();
47216
47259
  return () => {
47217
- observerRef.current?.disconnect();
47260
+ container.removeEventListener('scroll', handleScroll);
47261
+ if (scrollDebounceRef.current) {
47262
+ clearTimeout(scrollDebounceRef.current);
47263
+ }
47218
47264
  };
47219
- }, [treeData, loadMore, isLoading]);
47220
- // new useLayoutEffect to handle loading state
47221
- React.useLayoutEffect(() => {
47222
- if (!loading && isLoading === 'above' && pagination) {
47223
- const raf = requestAnimationFrame(() => {
47224
- handleScroll();
47225
- setIsLoading(null);
47226
- });
47227
- return () => {
47228
- cancelAnimationFrame(raf);
47229
- };
47230
- } else if (!loading) {
47265
+ }, [handleScroll, pagination]);
47266
+ // Track previous tree data for scroll restoration
47267
+ React.useEffect(() => {
47268
+ if (treeData.length > 0) {
47231
47269
  previousTreeDataRef.current = treeData;
47232
- setIsLoading(null);
47233
47270
  }
47234
- return undefined;
47235
- }, [loading, onScroll]);
47271
+ }, [treeData]);
47236
47272
  React.useEffect(() => {
47237
47273
  if (!loading && expanding) {
47238
47274
  setExpanding(null);
47239
- previousTreeDataRef.current = treeData;
47240
47275
  }
47241
47276
  }, [loading]);
47242
47277
  const handleToggleExpand = React.useCallback(node => {
@@ -47244,17 +47279,6 @@ const TableTreeFn = /*#__PURE__*/React.forwardRef(({
47244
47279
  setExpanding(node.key);
47245
47280
  onExpand?.(node);
47246
47281
  }, [onExpand, expanding]);
47247
- React.useEffect(() => {
47248
- const scrollDiv = containerRef.current;
47249
- if (scrollDiv && onScroll) {
47250
- scrollDiv.addEventListener('scroll', onScroll);
47251
- }
47252
- return () => {
47253
- if (scrollDiv && onScroll) {
47254
- scrollDiv.removeEventListener('scroll', onScroll);
47255
- }
47256
- };
47257
- }, [onScroll]);
47258
47282
  const handleCheckBoxChange = React.useCallback((e, node) => {
47259
47283
  if (expanding) return;
47260
47284
  onChange?.(e, node);
@@ -47263,18 +47287,6 @@ const TableTreeFn = /*#__PURE__*/React.forwardRef(({
47263
47287
  if (expanding) return;
47264
47288
  onClick?.(e, node);
47265
47289
  }, [onClick, expanding]);
47266
- React.useEffect(() => {
47267
- console.log(`Navigating to tree nodeFromUseEffect: ${navigateTreeNode}`);
47268
- if (navigateTreeNode) {
47269
- const node = document.getElementById(navigateTreeNode);
47270
- if (node) {
47271
- node.scrollIntoView({
47272
- behavior: 'smooth',
47273
- block: 'nearest'
47274
- });
47275
- }
47276
- }
47277
- }, [navigateTreeNode]);
47278
47290
  const DEFAULT_COLUMN_WIDTH = 400;
47279
47291
  const calculateFrozenWidth = (columnData, freezeColumns) => {
47280
47292
  return columnData.slice(0, freezeColumns).reduce((acc, col) => acc + parseInt(col.width || `${DEFAULT_COLUMN_WIDTH}`, 10), 0);
@@ -47289,7 +47301,6 @@ const TableTreeFn = /*#__PURE__*/React.forwardRef(({
47289
47301
  children: jsxRuntime.jsx("div", {
47290
47302
  className: `table-scrollable ${treeData.length ? '' : 'table-empty'}`,
47291
47303
  ref: containerRef,
47292
- id: "ff-table-tree-scroll-container",
47293
47304
  style: {
47294
47305
  '--table-height': treeData.length ? height : 'auto',
47295
47306
  '--frozen-column-width': freezeColumns ? `${frozenWidth}px` : '0px',