From 1c8709f52058da835b5ced160bdbb94913be63b7 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 9 Mar 2025 22:07:14 -0400 Subject: [PATCH] Rearrange docs --- .../ValidationStep-Refactoring-Plan.md | 0 ...ValidationStepNew-Implementation-Status.md | 0 {inventory/docs => docs}/fix-multi-select.md | 0 docs/validation-table-scroll-issue.md | 227 ++++++++++++++++++ 4 files changed, 227 insertions(+) rename {inventory/docs => docs}/ValidationStep-Refactoring-Plan.md (100%) rename {inventory/docs => docs}/ValidationStepNew-Implementation-Status.md (100%) rename {inventory/docs => docs}/fix-multi-select.md (100%) create mode 100644 docs/validation-table-scroll-issue.md diff --git a/inventory/docs/ValidationStep-Refactoring-Plan.md b/docs/ValidationStep-Refactoring-Plan.md similarity index 100% rename from inventory/docs/ValidationStep-Refactoring-Plan.md rename to docs/ValidationStep-Refactoring-Plan.md diff --git a/inventory/docs/ValidationStepNew-Implementation-Status.md b/docs/ValidationStepNew-Implementation-Status.md similarity index 100% rename from inventory/docs/ValidationStepNew-Implementation-Status.md rename to docs/ValidationStepNew-Implementation-Status.md diff --git a/inventory/docs/fix-multi-select.md b/docs/fix-multi-select.md similarity index 100% rename from inventory/docs/fix-multi-select.md rename to docs/fix-multi-select.md diff --git a/docs/validation-table-scroll-issue.md b/docs/validation-table-scroll-issue.md new file mode 100644 index 0000000..c8969f2 --- /dev/null +++ b/docs/validation-table-scroll-issue.md @@ -0,0 +1,227 @@ +# ValidationTable Scroll Position Issue + +## Problem Description + +The `ValidationTable` component in the inventory application suffers from a persistent scroll position issue. When the table content updates or re-renders, the scroll position resets to the top left corner. This creates a poor user experience, especially when users are working with large datasets and need to maintain their position while making edits or filtering data. + +Specific behaviors: +- Scroll position resets to the top left corner during re-renders +- User loses their place in the table when data is updated +- The table does not preserve vertical or horizontal scroll position + +## Relevant Files + +- **`inventory/src/lib/react-spreadsheet-import/src/steps/ValidationStepNew/components/ValidationTable.tsx`** + - Main component that renders the validation table + - Handles scroll position management + +- **`inventory/src/lib/react-spreadsheet-import/src/steps/ValidationStepNew/components/ValidationContainer.tsx`** + - Parent component that wraps ValidationTable + - Creates an EnhancedValidationTable wrapper component + - Manages data and state for the validation table + +- **`inventory/src/lib/react-spreadsheet-import/src/steps/ValidationStepNew/hooks/useValidationState.tsx`** + - Provides state management and data manipulation functions + - Contains scroll-related code in the `updateRow` function + +- **`inventory/src/lib/react-spreadsheet-import/src/steps/ValidationStepNew/components/ValidationCell.tsx`** + - Renders individual cells in the table + - May influence re-renders that affect scroll position + +## Failed Attempts + +We've tried multiple approaches to fix the scroll position issue, none of which have been successful: + +### 1. Using Refs for Scroll Position + +```typescript +const scrollPosition = useRef({ + left: 0, + top: 0 +}); + +// Capture position on scroll +const handleScroll = useCallback(() => { + if (tableContainerRef.current) { + scrollPosition.current = { + left: tableContainerRef.current.scrollLeft, + top: tableContainerRef.current.scrollTop + }; + } +}, []); + +// Restore in useLayoutEffect +useLayoutEffect(() => { + const container = tableContainerRef.current; + if (container) { + const { left, top } = scrollPosition.current; + if (left || top) { + container.scrollLeft = left; + container.scrollTop = top; + } + } +}); +``` + +Result: Scroll position was still lost during updates. + +### 2. Multiple Restoration Attempts with Timeouts + +```typescript +// Multiple timeouts at different intervals +setTimeout(() => { + if (tableContainerRef.current) { + tableContainerRef.current.scrollTop = savedPosition.top; + tableContainerRef.current.scrollLeft = savedPosition.left; + } +}, 0); + +setTimeout(() => { + if (tableContainerRef.current) { + tableContainerRef.current.scrollTop = savedPosition.top; + tableContainerRef.current.scrollLeft = savedPosition.left; + } +}, 50); + +// Additional timeouts at 100ms, 300ms +``` + +Result: Still not reliable, scroll position would reset between timeouts or after all timeouts completed. + +### 3. Using MutationObserver and ResizeObserver + +```typescript +// Create a mutation observer to detect DOM changes +const mutationObserver = new MutationObserver(() => { + if (shouldPreserveScroll) { + restoreScrollPosition(); + } +}); + +// Start observing the table for DOM changes +mutationObserver.observe(scrollableContainer, { + childList: true, + subtree: true, + attributes: true, + attributeFilter: ['style', 'class'] +}); + +// Create a resize observer +const resizeObserver = new ResizeObserver(() => { + if (shouldPreserveScroll) { + restoreScrollPosition(); + } +}); + +// Observe the table container +resizeObserver.observe(scrollableContainer); +``` + +Result: Did not reliably maintain scroll position, and sometimes caused other rendering issues. + +### 4. Recursive Restoration Approach + +```typescript +let attempts = 0; +const maxAttempts = 5; + +const restore = () => { + if (tableContainerRef.current) { + tableContainerRef.current.scrollTop = y; + tableContainerRef.current.scrollLeft = x; + + attempts++; + if (attempts < maxAttempts) { + setTimeout(restore, 50 * attempts); + } + } +}; + +restore(); +``` + +Result: No improvement, scroll position still reset. + +### 5. Using React State for Scroll Position + +```typescript +const [scrollPos, setScrollPos] = useState<{top: number; left: number}>({top: 0, left: 0}); + +// Track the scroll event +useEffect(() => { + const handleScroll = () => { + if (scrollContainerRef.current) { + setScrollPos({ + top: scrollContainerRef.current.scrollTop, + left: scrollContainerRef.current.scrollLeft + }); + } + }; + + // Add scroll listener... +}, []); + +// Restore scroll position +useLayoutEffect(() => { + const container = scrollContainerRef.current; + const { top, left } = scrollPos; + + if (top > 0 || left > 0) { + requestAnimationFrame(() => { + if (container) { + container.scrollTop = top; + container.scrollLeft = left; + } + }); + } +}, [scrollPos, data]); +``` + +Result: Caused the screen to shake violently when scrolling and did not preserve position. + +### 6. Using Key Attribute for Stability + +```typescript +return ( +
+ {/* Table content */} +
+); +``` + +Result: Did not resolve the issue and may have contributed to rendering instability. + +### 7. Removing Scroll Management from Other Components + +We removed scroll position management code from: +- `useValidationState.tsx` (in the updateRow function) +- `ValidationContainer.tsx` (in the enhancedUpdateRow function) + +Result: This did not fix the issue either. + +## Current Understanding + +The scroll position issue appears to be complex and likely stems from multiple factors: + +1. React's virtual DOM reconciliation may be replacing the scroll container element during updates +2. The table uses complex memo patterns with custom equality checks that may not be working as expected +3. The data structure may be changing in ways that cause complete re-renders +4. The component hierarchy (with EnhancedValidationTable wrapper) may be affecting DOM stability + +## Next Steps to Consider + +Potential approaches that haven't been tried yet: + +1. Implement a completely separate scroll container that exists outside of React's rendering cycle +2. Use a third-party virtualized table library that handles scroll position natively +3. Restructure the component hierarchy to minimize re-renders +4. Use the React DevTools profiler to identify which components are causing re-renders +5. Consider simplifying the data structure to reduce the complexity of renders + +## Conclusion + +This issue has proven particularly challenging to resolve. The current ValidationTable implementation struggles with scroll position preservation despite multiple different approaches. A more fundamental restructuring of the component or its rendering approach may be necessary. \ No newline at end of file