# Plan: Viewport Resize Handling for list-table-v2 ## 1. Problem Analysis ### Current State - The `list-table-v2` component uses a probe row technique to dynamically measure row height when `rowHeight` is NOT explicitly set (dynamic height mode) - The `measureProbeRow` function (lines 217-231) already exists and correctly: - Clears `estimatedRowHeight.value` before re-measuring - Uses TWO `requestAnimationFrame` calls after `nextTick` to let el-table-v2 fully settle - Measures the probe row's `offsetHeight` ### Problem - When the viewport width changes, column widths may adjust (due to `flexGrow: 1` in `tableColumns` computed) - This can cause row heights to change, but currently there is no trigger to re-measure - Without re-measuring, the `estimatedRowHeight` may become inaccurate, causing layout issues ### Constraints (from previous attempts) 1. ResizeObserver on container caused errors in component setup - AVOID 2. Must use TWO `requestAnimationFrame` calls after `nextTick` for proper el-table-v2 settlement 3. Must clear `estimatedRowHeight` before re-measuring for el-table-v2 to recalculate properly --- ## 2. Implementation Approach ### Strategy Add a debounced window resize event listener that: 1. Checks if dynamic height mode is active (`shouldUseProbeRow`) 2. Calls the existing `measureProbeRow` function 3. Cleans up properly on component unmount ### Why Window Resize Instead of ResizeObserver - `el-auto-resizer` already handles container size changes internally - Window resize is the correct trigger because column widths change based on viewport width (via `flexGrow`) - ResizeObserver on container caused setup errors in previous attempts ### Debounce Strategy - Use lodash's `debounce` (already imported as `lodash-es`) - Debounce delay: ~200-300ms to avoid excessive recalculations during active resize - The debounced function will be created with `onMounted` and cleaned up with `onUnmounted` --- ## 3. Code Changes Needed ### File: `/home/hechang27/Documents/sprt/noob-components/packages/base/data/list-table-v2.vue` #### Import Additions (line 53) ```typescript import { ref, computed, watch, h, onMounted, onUpdated, onUnmounted, useSlots, renderSlot, nextTick } from "vue"; ``` #### New State Variable After line 66 (`const estimatedRowHeight = ref(undefined);`): ```typescript // Debounced resize handler for re-measuring probe row const debouncedResizeHandler = ref<() => void>(); ``` #### New Lifecycle Hooks After line 214 (after the existing `watch` block): ```typescript // Setup resize listener on mount onMounted(() => { // Create debounced handler debouncedResizeHandler.value = lodash.debounce(() => { // Only re-measure in dynamic height mode if (shouldUseProbeRow.value) { measureProbeRow(); } }, 250); // 250ms debounce delay // Attach window resize listener window.addEventListener('resize', debouncedResizeHandler.value); }); // Cleanup on unmount onUnmounted(() => { if (debouncedResizeHandler.value) { window.removeEventListener('resize', debouncedResizeHandler.value); debouncedResizeHandler.value.cancel(); // Cancel any pending debounce calls } }); ``` --- ## 4. Verification Steps ### Manual Testing 1. Open a page using `list-table-v2` without explicit `rowHeight` prop 2. Open browser DevTools and inspect a row element to see its height 3. Resize the browser window (change width) 4. Verify that: - No console errors occur during resize - The row height is recalculated correctly after resize settles - The table layout remains correct after resize ### Edge Cases to Verify 1. **Rapid resize**: Resize window quickly back and forth - should not cause errors or excessive measurements 2. **Minimum width**: Table should handle minimum width gracefully without breaking 3. **No explicit rowHeight**: Verify resize handling is NOT active when `rowHeight` IS set (fixed height mode) 4. **Unmount cleanup**: Navigate away from the page and verify no memory leaks or hanging listeners ### Code Review Checklist - [ ] `onUnmounted` is imported and used - [ ] Debounced handler is properly cancelled on unmount - [ ] `shouldUseProbeRow.value` check prevents unnecessary calls in fixed-height mode - [ ] Two RAF frames are used in `measureProbeRow` (existing pattern preserved) - [ ] `estimatedRowHeight` is cleared before re-measuring (existing pattern preserved) --- ## 5. Dependencies - lodash-es debounce (already imported) - Vue lifecycle hooks (already available) No new dependencies required.