cogsbox-state 0.5.287 → 0.5.288
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 +204 -201
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +31 -24
package/package.json
CHANGED
package/src/CogsState.tsx
CHANGED
|
@@ -1803,8 +1803,9 @@ function createProxyHandler<T>(
|
|
|
1803
1803
|
return (
|
|
1804
1804
|
options: VirtualViewOptions
|
|
1805
1805
|
): VirtualStateObjectResult<any[]> => {
|
|
1806
|
+
// --- CHANGE 1: itemHeight is now optional with a default ---
|
|
1806
1807
|
const {
|
|
1807
|
-
itemHeight = 50, //
|
|
1808
|
+
itemHeight = 50, // Serves as a fallback for unmeasured items
|
|
1808
1809
|
overscan = 5,
|
|
1809
1810
|
stickToBottom = false,
|
|
1810
1811
|
} = options;
|
|
@@ -1815,18 +1816,7 @@ function createProxyHandler<T>(
|
|
|
1815
1816
|
endIndex: 10,
|
|
1816
1817
|
});
|
|
1817
1818
|
|
|
1818
|
-
// ---
|
|
1819
|
-
const isAtBottomRef = useRef(stickToBottom);
|
|
1820
|
-
const previousTotalCountRef = useRef(0);
|
|
1821
|
-
const isInitialMountRef = useRef(true);
|
|
1822
|
-
|
|
1823
|
-
const sourceArray = getGlobalStore().getNestedState(
|
|
1824
|
-
stateKey,
|
|
1825
|
-
path
|
|
1826
|
-
) as any[];
|
|
1827
|
-
const totalCount = sourceArray.length;
|
|
1828
|
-
|
|
1829
|
-
// Helper to get an item's measured height or the default
|
|
1819
|
+
// --- CHANGE 2: Add a helper to get heights from shadow store ---
|
|
1830
1820
|
const getItemHeight = useCallback(
|
|
1831
1821
|
(index: number): number => {
|
|
1832
1822
|
const metadata = getGlobalStore
|
|
@@ -1837,7 +1827,18 @@ function createProxyHandler<T>(
|
|
|
1837
1827
|
[itemHeight, stateKey, path]
|
|
1838
1828
|
);
|
|
1839
1829
|
|
|
1840
|
-
|
|
1830
|
+
const isAtBottomRef = useRef(stickToBottom);
|
|
1831
|
+
const previousTotalCountRef = useRef(0);
|
|
1832
|
+
const isInitialMountRef = useRef(true);
|
|
1833
|
+
|
|
1834
|
+
const sourceArray = getGlobalStore().getNestedState(
|
|
1835
|
+
stateKey,
|
|
1836
|
+
path
|
|
1837
|
+
) as any[];
|
|
1838
|
+
const totalCount = sourceArray.length;
|
|
1839
|
+
|
|
1840
|
+
// --- CHANGE 3: Pre-calculate total height and item positions ---
|
|
1841
|
+
// This replaces all instances of `totalCount * itemHeight`.
|
|
1841
1842
|
const { totalHeight, positions } = useMemo(() => {
|
|
1842
1843
|
let currentHeight = 0;
|
|
1843
1844
|
const pos: number[] = [];
|
|
@@ -1848,6 +1849,7 @@ function createProxyHandler<T>(
|
|
|
1848
1849
|
return { totalHeight: currentHeight, positions: pos };
|
|
1849
1850
|
}, [totalCount, getItemHeight]);
|
|
1850
1851
|
|
|
1852
|
+
// This part is IDENTICAL to your original code
|
|
1851
1853
|
const virtualState = useMemo(() => {
|
|
1852
1854
|
const start = Math.max(0, range.startIndex);
|
|
1853
1855
|
const end = Math.min(totalCount, range.endIndex);
|
|
@@ -1869,13 +1871,16 @@ function createProxyHandler<T>(
|
|
|
1869
1871
|
const wasAtBottom = isAtBottomRef.current;
|
|
1870
1872
|
const listGrew = totalCount > previousTotalCountRef.current;
|
|
1871
1873
|
previousTotalCountRef.current = totalCount;
|
|
1874
|
+
|
|
1872
1875
|
const handleScroll = () => {
|
|
1873
1876
|
const { scrollTop, clientHeight, scrollHeight } = container;
|
|
1874
1877
|
isAtBottomRef.current =
|
|
1875
1878
|
scrollHeight - scrollTop - clientHeight < 10;
|
|
1876
1879
|
|
|
1877
|
-
//
|
|
1880
|
+
// --- CHANGE 4: Update scroll logic to use positions array ---
|
|
1881
|
+
// This is the dynamic equivalent of `Math.floor(scrollTop / itemHeight)`.
|
|
1878
1882
|
let startIndex = 0;
|
|
1883
|
+
// A simple loop is robust and easy to understand.
|
|
1879
1884
|
for (let i = 0; i < positions.length; i++) {
|
|
1880
1885
|
if (positions[i]! >= scrollTop) {
|
|
1881
1886
|
startIndex = i;
|
|
@@ -1883,16 +1888,15 @@ function createProxyHandler<T>(
|
|
|
1883
1888
|
}
|
|
1884
1889
|
}
|
|
1885
1890
|
|
|
1886
|
-
// Find the end index by seeing how many items fit in the viewport
|
|
1887
1891
|
let endIndex = startIndex;
|
|
1888
1892
|
while (
|
|
1889
1893
|
endIndex < totalCount &&
|
|
1894
|
+
positions[endIndex] &&
|
|
1890
1895
|
positions[endIndex]! < scrollTop + clientHeight
|
|
1891
1896
|
) {
|
|
1892
1897
|
endIndex++;
|
|
1893
1898
|
}
|
|
1894
1899
|
|
|
1895
|
-
// Apply overscan
|
|
1896
1900
|
startIndex = Math.max(0, startIndex - overscan);
|
|
1897
1901
|
endIndex = Math.min(totalCount, endIndex + overscan);
|
|
1898
1902
|
|
|
@@ -1901,7 +1905,7 @@ function createProxyHandler<T>(
|
|
|
1901
1905
|
prevRange.startIndex !== startIndex ||
|
|
1902
1906
|
prevRange.endIndex !== endIndex
|
|
1903
1907
|
) {
|
|
1904
|
-
return { startIndex, endIndex };
|
|
1908
|
+
return { startIndex: startIndex, endIndex: endIndex };
|
|
1905
1909
|
}
|
|
1906
1910
|
return prevRange;
|
|
1907
1911
|
});
|
|
@@ -1911,7 +1915,7 @@ function createProxyHandler<T>(
|
|
|
1911
1915
|
passive: true,
|
|
1912
1916
|
});
|
|
1913
1917
|
|
|
1914
|
-
//
|
|
1918
|
+
// This logic is IDENTICAL to your original code
|
|
1915
1919
|
if (stickToBottom) {
|
|
1916
1920
|
if (isInitialMountRef.current) {
|
|
1917
1921
|
container.scrollTo({
|
|
@@ -1927,12 +1931,12 @@ function createProxyHandler<T>(
|
|
|
1927
1931
|
});
|
|
1928
1932
|
}
|
|
1929
1933
|
}
|
|
1930
|
-
|
|
1931
1934
|
isInitialMountRef.current = false;
|
|
1932
|
-
handleScroll();
|
|
1935
|
+
handleScroll();
|
|
1933
1936
|
|
|
1934
1937
|
return () =>
|
|
1935
1938
|
container.removeEventListener("scroll", handleScroll);
|
|
1939
|
+
// The dependencies are almost identical, just swapping itemHeight for `positions`
|
|
1936
1940
|
}, [totalCount, overscan, stickToBottom, positions]);
|
|
1937
1941
|
|
|
1938
1942
|
const scrollToBottom = useCallback(
|
|
@@ -1947,18 +1951,20 @@ function createProxyHandler<T>(
|
|
|
1947
1951
|
[]
|
|
1948
1952
|
);
|
|
1949
1953
|
|
|
1954
|
+
// --- CHANGE 5: Update scrollToIndex to use positions array ---
|
|
1950
1955
|
const scrollToIndex = useCallback(
|
|
1951
1956
|
(index: number, behavior: ScrollBehavior = "smooth") => {
|
|
1952
1957
|
if (containerRef.current && positions[index] !== undefined) {
|
|
1953
1958
|
containerRef.current.scrollTo({
|
|
1954
|
-
top: positions[index],
|
|
1959
|
+
top: positions[index], // Instead of `index * itemHeight`
|
|
1955
1960
|
behavior,
|
|
1956
1961
|
});
|
|
1957
1962
|
}
|
|
1958
1963
|
},
|
|
1959
|
-
[positions] // Depends on
|
|
1964
|
+
[positions] // Depends on `positions` now instead of `itemHeight`
|
|
1960
1965
|
);
|
|
1961
1966
|
|
|
1967
|
+
// --- CHANGE 6: Update props to use dynamic totalHeight and offsets ---
|
|
1962
1968
|
const virtualizerProps = {
|
|
1963
1969
|
outer: {
|
|
1964
1970
|
ref: containerRef,
|
|
@@ -1966,12 +1972,13 @@ function createProxyHandler<T>(
|
|
|
1966
1972
|
},
|
|
1967
1973
|
inner: {
|
|
1968
1974
|
style: {
|
|
1969
|
-
height: `${totalHeight}px`,
|
|
1975
|
+
height: `${totalHeight}px`, // Use calculated total height
|
|
1970
1976
|
position: "relative",
|
|
1971
1977
|
},
|
|
1972
1978
|
},
|
|
1973
1979
|
list: {
|
|
1974
1980
|
style: {
|
|
1981
|
+
// Use the pre-calculated position of the first visible item
|
|
1975
1982
|
transform: `translateY(${positions[range.startIndex] || 0}px)`,
|
|
1976
1983
|
},
|
|
1977
1984
|
},
|