cogsbox-state 0.5.345 → 0.5.347
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/dist/CogsState.jsx +644 -646
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +56 -49
package/package.json
CHANGED
package/src/CogsState.tsx
CHANGED
|
@@ -1807,29 +1807,12 @@ function createProxyHandler<T>(
|
|
|
1807
1807
|
overscan = 6,
|
|
1808
1808
|
stickToBottom = false,
|
|
1809
1809
|
} = options;
|
|
1810
|
-
|
|
1811
|
-
stateKey,
|
|
1812
|
-
path
|
|
1813
|
-
) as any[];
|
|
1810
|
+
|
|
1814
1811
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
.getNestedState(stateKey, path) as any[];
|
|
1820
|
-
if (stickToBottom) {
|
|
1821
|
-
const visibleCount = 10; // A reasonable guess for initial render
|
|
1822
|
-
return {
|
|
1823
|
-
startIndex: Math.max(
|
|
1824
|
-
0,
|
|
1825
|
-
sourceArray.length - visibleCount - overscan
|
|
1826
|
-
),
|
|
1827
|
-
endIndex: sourceArray.length,
|
|
1828
|
-
};
|
|
1829
|
-
}
|
|
1830
|
-
return { startIndex: 0, endIndex: 10 };
|
|
1831
|
-
};
|
|
1832
|
-
const [range, setRange] = useState(initialRange);
|
|
1812
|
+
const [range, setRange] = useState({
|
|
1813
|
+
startIndex: 0,
|
|
1814
|
+
endIndex: 10,
|
|
1815
|
+
});
|
|
1833
1816
|
const isLockedToBottomRef = useRef(stickToBottom);
|
|
1834
1817
|
|
|
1835
1818
|
const [shadowUpdateTrigger, setShadowUpdateTrigger] = useState(0);
|
|
@@ -1843,6 +1826,10 @@ function createProxyHandler<T>(
|
|
|
1843
1826
|
return unsubscribe;
|
|
1844
1827
|
}, [stateKey]);
|
|
1845
1828
|
|
|
1829
|
+
const sourceArray = getGlobalStore().getNestedState(
|
|
1830
|
+
stateKey,
|
|
1831
|
+
path
|
|
1832
|
+
) as any[];
|
|
1846
1833
|
const totalCount = sourceArray.length;
|
|
1847
1834
|
|
|
1848
1835
|
const { totalHeight, positions } = useMemo(() => {
|
|
@@ -1880,47 +1867,67 @@ function createProxyHandler<T>(
|
|
|
1880
1867
|
});
|
|
1881
1868
|
}, [range.startIndex, range.endIndex, sourceArray, totalCount]);
|
|
1882
1869
|
|
|
1883
|
-
//
|
|
1870
|
+
// --- YOUR SCROLLING ALGORITHM (UNCHANGED and WORKING) ---
|
|
1871
|
+
// This effect is the entry point. It triggers when new items are added.
|
|
1884
1872
|
useLayoutEffect(() => {
|
|
1885
1873
|
const container = containerRef.current;
|
|
1874
|
+
// Only run if we are supposed to be at the bottom.
|
|
1886
1875
|
if (
|
|
1887
1876
|
!container ||
|
|
1888
|
-
!
|
|
1889
|
-
|
|
1877
|
+
!isLockedToBottomRef.current ||
|
|
1878
|
+
totalCount === 0
|
|
1890
1879
|
) {
|
|
1891
1880
|
return;
|
|
1892
1881
|
}
|
|
1893
1882
|
|
|
1894
|
-
// STEP 1:
|
|
1895
|
-
const
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
//
|
|
1906
|
-
const
|
|
1883
|
+
// STEP 1: Set the range to the end so the last items are rendered.
|
|
1884
|
+
const visibleCount = 10;
|
|
1885
|
+
setRange({
|
|
1886
|
+
startIndex: Math.max(0, totalCount - visibleCount - overscan),
|
|
1887
|
+
endIndex: totalCount,
|
|
1888
|
+
});
|
|
1889
|
+
|
|
1890
|
+
// STEP 2: Start the LOOP.
|
|
1891
|
+
let loopCount = 0;
|
|
1892
|
+
const intervalId = setInterval(() => {
|
|
1893
|
+
loopCount++;
|
|
1894
|
+
// The Check: Get the last item's height FROM THE SHADOW OBJECT.
|
|
1895
|
+
const lastItemIndex = totalCount - 1;
|
|
1896
|
+
const shadowArray =
|
|
1897
|
+
getGlobalStore
|
|
1898
|
+
.getState()
|
|
1899
|
+
.getShadowMetadata(stateKey, path) || [];
|
|
1900
|
+
const lastItemHeight =
|
|
1901
|
+
shadowArray[lastItemIndex]?.virtualizer?.itemHeight || 0;
|
|
1902
|
+
|
|
1903
|
+
if (lastItemHeight > 0) {
|
|
1904
|
+
// EXIT CONDITION MET
|
|
1905
|
+
clearInterval(intervalId); // Stop the loop.
|
|
1906
|
+
|
|
1907
|
+
// STEP 3: Scroll.
|
|
1907
1908
|
container.scrollTo({
|
|
1908
1909
|
top: container.scrollHeight,
|
|
1909
1910
|
behavior: "smooth",
|
|
1910
1911
|
});
|
|
1911
|
-
}
|
|
1912
|
+
} else {
|
|
1913
|
+
if (loopCount > 20) {
|
|
1914
|
+
// Safety break
|
|
1915
|
+
clearInterval(intervalId);
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
}, 100);
|
|
1912
1919
|
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
// It will automatically re-run when the measurement comes in (via shadowUpdateTrigger).
|
|
1917
|
-
}, [totalCount, totalHeight, stickToBottom]); // Re-run when layout changes.
|
|
1920
|
+
// Cleanup: Stop the loop if the component unmounts.
|
|
1921
|
+
return () => clearInterval(intervalId);
|
|
1922
|
+
}, [totalCount]); // This whole process triggers ONLY when totalCount changes.
|
|
1918
1923
|
|
|
1919
|
-
//
|
|
1924
|
+
// --- THE FIX IS HERE ---
|
|
1925
|
+
// This effect now correctly handles user scrolling AND updates the view.
|
|
1920
1926
|
useEffect(() => {
|
|
1921
1927
|
const container = containerRef.current;
|
|
1922
1928
|
if (!container) return;
|
|
1923
1929
|
|
|
1930
|
+
// This function now always has the LATEST totalCount and positions.
|
|
1924
1931
|
const updateVirtualRange = () => {
|
|
1925
1932
|
const { scrollTop, clientHeight } = container;
|
|
1926
1933
|
let low = 0,
|
|
@@ -1954,18 +1961,19 @@ function createProxyHandler<T>(
|
|
|
1954
1961
|
if (!isAtBottom) {
|
|
1955
1962
|
isLockedToBottomRef.current = false;
|
|
1956
1963
|
}
|
|
1964
|
+
// This always calls the fresh version of updateVirtualRange.
|
|
1957
1965
|
updateVirtualRange();
|
|
1958
1966
|
};
|
|
1959
1967
|
|
|
1960
1968
|
container.addEventListener("scroll", handleUserScroll, {
|
|
1961
1969
|
passive: true,
|
|
1962
1970
|
});
|
|
1963
|
-
//
|
|
1964
|
-
updateVirtualRange();
|
|
1971
|
+
updateVirtualRange(); // Update range on initial load and when data changes.
|
|
1965
1972
|
|
|
1973
|
+
// This cleanup is crucial. It removes the old listener before adding a new one.
|
|
1966
1974
|
return () =>
|
|
1967
1975
|
container.removeEventListener("scroll", handleUserScroll);
|
|
1968
|
-
}, [totalCount, positions]);
|
|
1976
|
+
}, [totalCount, positions]); // Its dependency array now includes totalCount and positions.
|
|
1969
1977
|
|
|
1970
1978
|
const scrollToBottom = useCallback(
|
|
1971
1979
|
(behavior: ScrollBehavior = "smooth") => {
|
|
@@ -2010,7 +2018,6 @@ function createProxyHandler<T>(
|
|
|
2010
2018
|
},
|
|
2011
2019
|
},
|
|
2012
2020
|
};
|
|
2013
|
-
|
|
2014
2021
|
return {
|
|
2015
2022
|
virtualState,
|
|
2016
2023
|
virtualizerProps,
|