cogsbox-state 0.5.295 → 0.5.296
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 +314 -327
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +27 -39
package/package.json
CHANGED
package/src/CogsState.tsx
CHANGED
|
@@ -1802,7 +1802,6 @@ function createProxyHandler<T>(
|
|
|
1802
1802
|
return (
|
|
1803
1803
|
options: VirtualViewOptions
|
|
1804
1804
|
): VirtualStateObjectResult<any[]> => {
|
|
1805
|
-
// --- CHANGE 1: itemHeight is now optional, with a default fallback.
|
|
1806
1805
|
const {
|
|
1807
1806
|
itemHeight = 50, // Default/estimated height
|
|
1808
1807
|
overscan = 5,
|
|
@@ -1815,7 +1814,6 @@ function createProxyHandler<T>(
|
|
|
1815
1814
|
endIndex: 10,
|
|
1816
1815
|
});
|
|
1817
1816
|
|
|
1818
|
-
// --- CHANGE 2: Add a helper to get the real height of each item. ---
|
|
1819
1817
|
const getItemHeight = useCallback(
|
|
1820
1818
|
(index: number): number => {
|
|
1821
1819
|
const metadata = getGlobalStore
|
|
@@ -1826,7 +1824,6 @@ function createProxyHandler<T>(
|
|
|
1826
1824
|
[itemHeight, stateKey, path]
|
|
1827
1825
|
);
|
|
1828
1826
|
|
|
1829
|
-
// --- These refs are from your original code. NO CHANGE. ---
|
|
1830
1827
|
const isAtBottomRef = useRef(stickToBottom);
|
|
1831
1828
|
const previousTotalCountRef = useRef(0);
|
|
1832
1829
|
const isInitialMountRef = useRef(true);
|
|
@@ -1837,19 +1834,18 @@ function createProxyHandler<T>(
|
|
|
1837
1834
|
) as any[];
|
|
1838
1835
|
const totalCount = sourceArray.length;
|
|
1839
1836
|
|
|
1840
|
-
// --- CHANGE 3: Calculate the total height and position of each item. ---
|
|
1841
|
-
// This is the only new block of logic required.
|
|
1842
1837
|
const { totalHeight, positions } = useMemo(() => {
|
|
1843
1838
|
let height = 0;
|
|
1844
1839
|
const pos: number[] = [];
|
|
1845
1840
|
for (let i = 0; i < totalCount; i++) {
|
|
1846
1841
|
pos[i] = height;
|
|
1847
1842
|
height += getItemHeight(i);
|
|
1843
|
+
console.log("height", getItemHeight(i), height);
|
|
1848
1844
|
}
|
|
1849
1845
|
return { totalHeight: height, positions: pos };
|
|
1850
1846
|
}, [totalCount, getItemHeight]);
|
|
1851
1847
|
|
|
1852
|
-
//
|
|
1848
|
+
// This logic is IDENTICAL to your original code.
|
|
1853
1849
|
const virtualState = useMemo(() => {
|
|
1854
1850
|
const start = Math.max(0, range.startIndex);
|
|
1855
1851
|
const end = Math.min(totalCount, range.endIndex);
|
|
@@ -1864,8 +1860,7 @@ function createProxyHandler<T>(
|
|
|
1864
1860
|
});
|
|
1865
1861
|
}, [range.startIndex, range.endIndex, sourceArray, totalCount]);
|
|
1866
1862
|
|
|
1867
|
-
//
|
|
1868
|
-
// --- We only change the math inside handleScroll. ---
|
|
1863
|
+
// This useLayoutEffect is from your original code.
|
|
1869
1864
|
useLayoutEffect(() => {
|
|
1870
1865
|
const container = containerRef.current;
|
|
1871
1866
|
if (!container) return;
|
|
@@ -1879,19 +1874,26 @@ function createProxyHandler<T>(
|
|
|
1879
1874
|
isAtBottomRef.current =
|
|
1880
1875
|
scrollHeight - scrollTop - clientHeight < 10;
|
|
1881
1876
|
|
|
1882
|
-
// ---
|
|
1883
|
-
// This
|
|
1884
|
-
let
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1877
|
+
// --- THE ROBUST FIX: Binary search to find the start index ---
|
|
1878
|
+
// This is extremely fast and correctly handles all scroll positions.
|
|
1879
|
+
let search = (list: number[], value: number) => {
|
|
1880
|
+
let low = 0;
|
|
1881
|
+
let high = list.length - 1;
|
|
1882
|
+
while (low <= high) {
|
|
1883
|
+
const mid = Math.floor((low + high) / 2);
|
|
1884
|
+
const midValue = list[mid]!;
|
|
1885
|
+
if (midValue < value) {
|
|
1886
|
+
low = mid + 1;
|
|
1887
|
+
} else {
|
|
1888
|
+
high = mid - 1;
|
|
1889
|
+
}
|
|
1890
1890
|
}
|
|
1891
|
-
|
|
1891
|
+
return low;
|
|
1892
|
+
};
|
|
1893
|
+
|
|
1894
|
+
let startIndex = search(positions, scrollTop);
|
|
1892
1895
|
|
|
1893
1896
|
let endIndex = startIndex;
|
|
1894
|
-
// Find the first item whose top position is past the bottom of the viewport.
|
|
1895
1897
|
while (
|
|
1896
1898
|
endIndex < totalCount &&
|
|
1897
1899
|
positions[endIndex]! < scrollTop + clientHeight
|
|
@@ -1899,23 +1901,15 @@ function createProxyHandler<T>(
|
|
|
1899
1901
|
endIndex++;
|
|
1900
1902
|
}
|
|
1901
1903
|
|
|
1902
|
-
// Apply overscan, identical to your original code.
|
|
1903
1904
|
startIndex = Math.max(0, startIndex - overscan);
|
|
1904
1905
|
endIndex = Math.min(totalCount, endIndex + overscan);
|
|
1905
|
-
console.log(
|
|
1906
|
-
"startIndex",
|
|
1907
|
-
startIndex,
|
|
1908
|
-
"endIndex",
|
|
1909
|
-
endIndex,
|
|
1910
|
-
"totalHeight",
|
|
1911
|
-
totalHeight
|
|
1912
|
-
);
|
|
1906
|
+
console.log("startIndex", startIndex, "endIndex", endIndex);
|
|
1913
1907
|
setRange((prevRange) => {
|
|
1914
1908
|
if (
|
|
1915
1909
|
prevRange.startIndex !== startIndex ||
|
|
1916
1910
|
prevRange.endIndex !== endIndex
|
|
1917
1911
|
) {
|
|
1918
|
-
return { startIndex
|
|
1912
|
+
return { startIndex, endIndex };
|
|
1919
1913
|
}
|
|
1920
1914
|
return prevRange;
|
|
1921
1915
|
});
|
|
@@ -1925,7 +1919,7 @@ function createProxyHandler<T>(
|
|
|
1925
1919
|
passive: true,
|
|
1926
1920
|
});
|
|
1927
1921
|
|
|
1928
|
-
//
|
|
1922
|
+
// This stickToBottom logic is IDENTICAL to your original.
|
|
1929
1923
|
if (stickToBottom) {
|
|
1930
1924
|
if (isInitialMountRef.current) {
|
|
1931
1925
|
container.scrollTo({
|
|
@@ -1947,7 +1941,6 @@ function createProxyHandler<T>(
|
|
|
1947
1941
|
|
|
1948
1942
|
return () =>
|
|
1949
1943
|
container.removeEventListener("scroll", handleScroll);
|
|
1950
|
-
// --- We swap `itemHeight` for `positions` in the dependency array. ---
|
|
1951
1944
|
}, [totalCount, overscan, stickToBottom, positions]);
|
|
1952
1945
|
|
|
1953
1946
|
const scrollToBottom = useCallback(
|
|
@@ -1962,34 +1955,29 @@ function createProxyHandler<T>(
|
|
|
1962
1955
|
[]
|
|
1963
1956
|
);
|
|
1964
1957
|
|
|
1965
|
-
// --- CHANGE 5: Update scrollToIndex to use the positions array. ---
|
|
1966
1958
|
const scrollToIndex = useCallback(
|
|
1967
1959
|
(index: number, behavior: ScrollBehavior = "smooth") => {
|
|
1968
1960
|
if (containerRef.current) {
|
|
1969
1961
|
containerRef.current.scrollTo({
|
|
1970
|
-
top: positions[index] || 0,
|
|
1962
|
+
top: positions[index] || 0,
|
|
1971
1963
|
behavior,
|
|
1972
1964
|
});
|
|
1973
1965
|
}
|
|
1974
1966
|
},
|
|
1975
|
-
[positions]
|
|
1967
|
+
[positions]
|
|
1976
1968
|
);
|
|
1977
1969
|
|
|
1978
|
-
// --- CHANGE 6: Update virtualizer props to use dynamic values. ---
|
|
1979
1970
|
const virtualizerProps = {
|
|
1980
1971
|
outer: {
|
|
1981
1972
|
ref: containerRef,
|
|
1982
1973
|
style: { overflowY: "auto", height: "100%" },
|
|
1983
1974
|
},
|
|
1984
1975
|
inner: {
|
|
1985
|
-
style: {
|
|
1986
|
-
height: `${totalHeight}px`, // Use calculated dynamic height
|
|
1987
|
-
position: "relative",
|
|
1988
|
-
},
|
|
1976
|
+
style: { height: `${totalHeight}px`, position: "relative" },
|
|
1989
1977
|
},
|
|
1990
1978
|
list: {
|
|
1991
1979
|
style: {
|
|
1992
|
-
transform: `translateY(${positions[range.startIndex] || 0}px)`,
|
|
1980
|
+
transform: `translateY(${positions[range.startIndex] || 0}px)`,
|
|
1993
1981
|
},
|
|
1994
1982
|
},
|
|
1995
1983
|
};
|