cogsbox-state 0.5.375 → 0.5.377
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 +455 -457
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +29 -48
package/package.json
CHANGED
package/src/CogsState.tsx
CHANGED
|
@@ -1827,8 +1827,7 @@ function createProxyHandler<T>(
|
|
|
1827
1827
|
const isProgrammaticScroll = useRef(false);
|
|
1828
1828
|
const prevTotalCountRef = useRef(0);
|
|
1829
1829
|
const prevDepsRef = useRef(dependencies);
|
|
1830
|
-
const
|
|
1831
|
-
|
|
1830
|
+
const lastUpdateAtScrollTop = useRef(0);
|
|
1832
1831
|
const [shadowUpdateTrigger, setShadowUpdateTrigger] = useState(0);
|
|
1833
1832
|
|
|
1834
1833
|
useEffect(() => {
|
|
@@ -2001,71 +2000,49 @@ function createProxyHandler<T>(
|
|
|
2001
2000
|
const container = containerRef.current;
|
|
2002
2001
|
if (!container) return;
|
|
2003
2002
|
|
|
2004
|
-
//
|
|
2005
|
-
|
|
2006
|
-
const scrollThreshold = itemHeight / 2;
|
|
2003
|
+
// The scroll distance threshold. One item's height is a great default.
|
|
2004
|
+
const scrollThreshold = itemHeight;
|
|
2007
2005
|
|
|
2008
2006
|
const handleUserScroll = () => {
|
|
2009
|
-
//
|
|
2007
|
+
// Essential guard for our own programmatic scrolls.
|
|
2010
2008
|
if (isProgrammaticScroll.current) {
|
|
2011
2009
|
return;
|
|
2012
2010
|
}
|
|
2013
2011
|
|
|
2014
2012
|
const scrollTop = container.scrollTop;
|
|
2015
2013
|
|
|
2016
|
-
// ---
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
scrollTop -
|
|
2020
|
-
container.clientHeight <
|
|
2021
|
-
1;
|
|
2022
|
-
|
|
2023
|
-
if (!isAtBottom) {
|
|
2024
|
-
if (status !== "IDLE_NOT_AT_BOTTOM") {
|
|
2025
|
-
console.log(
|
|
2026
|
-
"USER ACTION: Scrolled up -> IDLE_NOT_AT_BOTTOM"
|
|
2027
|
-
);
|
|
2028
|
-
setStatus("IDLE_NOT_AT_BOTTOM");
|
|
2029
|
-
}
|
|
2030
|
-
shouldNotScroll.current = true;
|
|
2031
|
-
} else {
|
|
2032
|
-
if (status === "IDLE_NOT_AT_BOTTOM") {
|
|
2033
|
-
console.log(
|
|
2034
|
-
"USER ACTION: Scrolled back to bottom -> LOCKED_AT_BOTTOM"
|
|
2035
|
-
);
|
|
2036
|
-
setStatus("LOCKED_AT_BOTTOM");
|
|
2037
|
-
}
|
|
2038
|
-
shouldNotScroll.current = false;
|
|
2039
|
-
}
|
|
2040
|
-
|
|
2041
|
-
// --- Part 2: The "Smarter" Threshold Check ---
|
|
2042
|
-
|
|
2043
|
-
// Check if the scroll distance is greater than our threshold.
|
|
2044
|
-
// Math.abs() handles both scrolling up and down.
|
|
2014
|
+
// --- THE CORE LOGIC YOU REQUESTED ---
|
|
2015
|
+
// Is the user just wiggling the scrollbar? If so, exit.
|
|
2016
|
+
// This is a very cheap check that runs on every scroll event.
|
|
2045
2017
|
if (
|
|
2046
|
-
Math.abs(scrollTop -
|
|
2018
|
+
Math.abs(scrollTop - lastUpdateAtScrollTop.current) <
|
|
2047
2019
|
scrollThreshold
|
|
2048
2020
|
) {
|
|
2049
|
-
// Not scrolled far enough, do nothing.
|
|
2050
2021
|
return;
|
|
2051
2022
|
}
|
|
2052
2023
|
|
|
2053
|
-
//
|
|
2054
|
-
lastScrollTopRef.current = scrollTop;
|
|
2024
|
+
// --- IF WE ARE HERE, WE HAVE SCROLLED A "DECENT AMOUNT" ---
|
|
2055
2025
|
|
|
2056
|
-
console.log(
|
|
2026
|
+
console.log(
|
|
2027
|
+
`Threshold passed at ${scrollTop}px. Recalculating range...`
|
|
2028
|
+
);
|
|
2057
2029
|
|
|
2058
|
-
//
|
|
2059
|
-
// This code now only runs when it's actually needed.
|
|
2030
|
+
// NOW we do the expensive work.
|
|
2060
2031
|
const { clientHeight } = container;
|
|
2061
|
-
let
|
|
2062
|
-
|
|
2032
|
+
let high = totalCount - 1;
|
|
2033
|
+
let low = 0;
|
|
2034
|
+
let topItemIndex = 0;
|
|
2063
2035
|
while (low <= high) {
|
|
2064
2036
|
const mid = Math.floor((low + high) / 2);
|
|
2065
|
-
if (positions[mid]! < scrollTop)
|
|
2066
|
-
|
|
2037
|
+
if (positions[mid]! < scrollTop) {
|
|
2038
|
+
topItemIndex = mid;
|
|
2039
|
+
low = mid + 1;
|
|
2040
|
+
} else {
|
|
2041
|
+
high = mid - 1;
|
|
2042
|
+
}
|
|
2067
2043
|
}
|
|
2068
|
-
|
|
2044
|
+
|
|
2045
|
+
const startIndex = Math.max(0, topItemIndex - overscan);
|
|
2069
2046
|
let endIndex = startIndex;
|
|
2070
2047
|
const visibleEnd = scrollTop + clientHeight;
|
|
2071
2048
|
while (
|
|
@@ -2074,10 +2051,14 @@ function createProxyHandler<T>(
|
|
|
2074
2051
|
) {
|
|
2075
2052
|
endIndex++;
|
|
2076
2053
|
}
|
|
2054
|
+
|
|
2077
2055
|
setRange({
|
|
2078
2056
|
startIndex,
|
|
2079
2057
|
endIndex: Math.min(totalCount, endIndex + overscan),
|
|
2080
2058
|
});
|
|
2059
|
+
|
|
2060
|
+
// Finally, we record that we did the work at THIS scroll position.
|
|
2061
|
+
lastUpdateAtScrollTop.current = scrollTop;
|
|
2081
2062
|
};
|
|
2082
2063
|
|
|
2083
2064
|
container.addEventListener("scroll", handleUserScroll, {
|
|
@@ -2085,7 +2066,7 @@ function createProxyHandler<T>(
|
|
|
2085
2066
|
});
|
|
2086
2067
|
return () =>
|
|
2087
2068
|
container.removeEventListener("scroll", handleUserScroll);
|
|
2088
|
-
}, [totalCount, positions,
|
|
2069
|
+
}, [totalCount, positions, itemHeight, overscan, status]);
|
|
2089
2070
|
|
|
2090
2071
|
const scrollToBottom = useCallback(() => {
|
|
2091
2072
|
console.log(
|