cogsbox-state 0.5.422 → 0.5.424
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 +590 -577
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +52 -24
package/package.json
CHANGED
package/src/CogsState.tsx
CHANGED
|
@@ -1824,7 +1824,7 @@ function createProxyHandler<T>(
|
|
|
1824
1824
|
const wasAtBottomRef = useRef(true);
|
|
1825
1825
|
const userHasScrolledAwayRef = useRef(false);
|
|
1826
1826
|
const previousCountRef = useRef(0);
|
|
1827
|
-
|
|
1827
|
+
const lastRangeRef = useRef(range);
|
|
1828
1828
|
// Subscribe to shadow state updates
|
|
1829
1829
|
useEffect(() => {
|
|
1830
1830
|
const unsubscribe = getGlobalStore
|
|
@@ -1930,12 +1930,8 @@ function createProxyHandler<T>(
|
|
|
1930
1930
|
setRange(newRange);
|
|
1931
1931
|
|
|
1932
1932
|
const timeoutId = setTimeout(() => {
|
|
1933
|
-
|
|
1934
|
-
containerRef.current.scrollTop =
|
|
1935
|
-
containerRef.current.scrollHeight;
|
|
1936
|
-
}
|
|
1933
|
+
scrollToIndex(totalCount - 1, "smooth");
|
|
1937
1934
|
}, 50);
|
|
1938
|
-
|
|
1939
1935
|
return () => clearTimeout(timeoutId);
|
|
1940
1936
|
}
|
|
1941
1937
|
|
|
@@ -1960,7 +1956,7 @@ function createProxyHandler<T>(
|
|
|
1960
1956
|
userHasScrolledAwayRef.current = true;
|
|
1961
1957
|
}
|
|
1962
1958
|
|
|
1963
|
-
// If user scrolls back to bottom,
|
|
1959
|
+
// If user scrolls back to bottom, cle
|
|
1964
1960
|
if (distanceFromBottom < 5) {
|
|
1965
1961
|
userHasScrolledAwayRef.current = false;
|
|
1966
1962
|
}
|
|
@@ -1983,10 +1979,26 @@ function createProxyHandler<T>(
|
|
|
1983
1979
|
endIndex = i;
|
|
1984
1980
|
}
|
|
1985
1981
|
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1982
|
+
const newStartIndex = Math.max(0, startIndex);
|
|
1983
|
+
const newEndIndex = Math.min(
|
|
1984
|
+
totalCount,
|
|
1985
|
+
endIndex + 1 + overscan
|
|
1986
|
+
);
|
|
1987
|
+
|
|
1988
|
+
// THE FIX: Only update state if the visible range of items has changed.
|
|
1989
|
+
if (
|
|
1990
|
+
newStartIndex !== lastRangeRef.current.startIndex ||
|
|
1991
|
+
newEndIndex !== lastRangeRef.current.endIndex
|
|
1992
|
+
) {
|
|
1993
|
+
lastRangeRef.current = {
|
|
1994
|
+
startIndex: newStartIndex,
|
|
1995
|
+
endIndex: newEndIndex,
|
|
1996
|
+
};
|
|
1997
|
+
setRange({
|
|
1998
|
+
startIndex: newStartIndex,
|
|
1999
|
+
endIndex: newEndIndex,
|
|
2000
|
+
});
|
|
2001
|
+
}
|
|
1990
2002
|
};
|
|
1991
2003
|
|
|
1992
2004
|
container.addEventListener("scroll", handleScroll, {
|
|
@@ -2023,32 +2035,48 @@ function createProxyHandler<T>(
|
|
|
2023
2035
|
containerRef.current.scrollHeight;
|
|
2024
2036
|
}
|
|
2025
2037
|
}, [scrollToLastItem]);
|
|
2026
|
-
|
|
2027
2038
|
const scrollToIndex = useCallback(
|
|
2028
2039
|
(index: number, behavior: ScrollBehavior = "smooth") => {
|
|
2040
|
+
const container = containerRef.current;
|
|
2041
|
+
if (!container) return;
|
|
2042
|
+
|
|
2043
|
+
const isLastItem = index === totalCount - 1;
|
|
2044
|
+
|
|
2045
|
+
// --- Special Case: The Last Item ---
|
|
2046
|
+
if (isLastItem) {
|
|
2047
|
+
// For the last item, scrollIntoView can fail. The most reliable method
|
|
2048
|
+
// is to scroll the parent container to its maximum scroll height.
|
|
2049
|
+
container.scrollTo({
|
|
2050
|
+
top: container.scrollHeight,
|
|
2051
|
+
behavior: behavior,
|
|
2052
|
+
});
|
|
2053
|
+
return; // We're done.
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
// --- Standard Case: All Other Items ---
|
|
2057
|
+
// For all other items, we find the ref and use scrollIntoView.
|
|
2029
2058
|
const shadowArray =
|
|
2030
2059
|
getGlobalStore
|
|
2031
2060
|
.getState()
|
|
2032
2061
|
.getShadowMetadata(stateKey, path) || [];
|
|
2033
2062
|
const itemData = shadowArray[index];
|
|
2063
|
+
const element = itemData?.virtualizer?.domRef;
|
|
2034
2064
|
|
|
2035
|
-
if (
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
}
|
|
2041
|
-
}
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
if (containerRef.current && positions[index] !== undefined) {
|
|
2045
|
-
containerRef.current.scrollTo({
|
|
2065
|
+
if (element) {
|
|
2066
|
+
// 'center' gives a better user experience for items in the middle of the list.
|
|
2067
|
+
element.scrollIntoView({
|
|
2068
|
+
behavior: behavior,
|
|
2069
|
+
block: "center",
|
|
2070
|
+
});
|
|
2071
|
+
} else if (positions[index] !== undefined) {
|
|
2072
|
+
// Fallback if the ref isn't available for some reason.
|
|
2073
|
+
container.scrollTo({
|
|
2046
2074
|
top: positions[index],
|
|
2047
2075
|
behavior,
|
|
2048
2076
|
});
|
|
2049
2077
|
}
|
|
2050
2078
|
},
|
|
2051
|
-
[positions, stateKey, path]
|
|
2079
|
+
[positions, stateKey, path, totalCount] // Add totalCount to the dependencies
|
|
2052
2080
|
);
|
|
2053
2081
|
|
|
2054
2082
|
const virtualizerProps = {
|