cogsbox-state 0.5.329 → 0.5.330

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogsbox-state",
3
- "version": "0.5.329",
3
+ "version": "0.5.330",
4
4
  "description": "React state management library with form controls and server sync",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/CogsState.tsx CHANGED
@@ -1816,11 +1816,9 @@ function createProxyHandler<T>(
1816
1816
 
1817
1817
  // This ref tracks if the user is locked to the bottom.
1818
1818
  const isLockedToBottomRef = useRef(stickToBottom);
1819
-
1819
+ const lastScrollPositionRef = useRef(0);
1820
1820
  // This state triggers a re-render when item heights change.
1821
1821
  const [shadowUpdateTrigger, setShadowUpdateTrigger] = useState(0);
1822
- const hasInitiallyLoadedRef = useRef(false);
1823
- const prevTotalCountRef = useRef(0);
1824
1822
 
1825
1823
  useEffect(() => {
1826
1824
  const unsubscribe = getGlobalStore
@@ -1941,38 +1939,31 @@ function createProxyHandler<T>(
1941
1939
  passive: true,
1942
1940
  });
1943
1941
 
1944
- // In your useLayoutEffect:
1945
- if (stickToBottom) {
1946
- // Check if this is initial load or new item
1947
- const isInitialLoad =
1948
- !hasInitiallyLoadedRef.current && totalCount > 0;
1949
- const isNewItem =
1950
- hasInitiallyLoadedRef.current &&
1951
- totalCount > prevTotalCountRef.current;
1952
-
1953
- scrollTimeoutId = setTimeout(() => {
1954
- console.log("totalHeight", totalHeight);
1955
- if (isLockedToBottomRef.current) {
1956
- container.scrollTo({
1957
- top: 999999999,
1958
- behavior: isNewItem ? "smooth" : "auto", // Only smooth for NEW items after initial load
1959
- });
1960
- }
1961
- }, 200);
1942
+ if (stickToBottom && isLockedToBottomRef.current) {
1943
+ const currentScrollHeight = container.scrollHeight;
1944
+
1945
+ // Only scroll if the height actually changed (new content rendered)
1946
+ if (currentScrollHeight > lastScrollPositionRef.current) {
1947
+ // Check if we're far from bottom (initial loads or large batches)
1948
+ const distanceFromBottom =
1949
+ currentScrollHeight -
1950
+ container.scrollTop -
1951
+ container.clientHeight;
1952
+ const isLargeGap =
1953
+ distanceFromBottom > container.clientHeight * 2;
1962
1954
 
1963
- // Mark as initially loaded after first run
1964
- if (isInitialLoad) {
1965
- hasInitiallyLoadedRef.current = true;
1955
+ container.scrollTo({
1956
+ top: 999999999,
1957
+ behavior: isLargeGap ? "auto" : "smooth", // Instant for big jumps, smooth for small
1958
+ });
1959
+
1960
+ lastScrollPositionRef.current = currentScrollHeight;
1966
1961
  }
1967
1962
  }
1968
-
1969
- // Update ref at the end
1970
- prevTotalCountRef.current = totalCount;
1971
1963
  updateVirtualRange();
1972
1964
 
1973
1965
  // Cleanup function is vital to prevent memory leaks.
1974
1966
  return () => {
1975
- clearTimeout(scrollTimeoutId);
1976
1967
  container.removeEventListener("scroll", handleUserScroll);
1977
1968
  };
1978
1969
  // This effect re-runs whenever the list size or item heights change.