cogsbox-state 0.5.310 → 0.5.312

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.310",
3
+ "version": "0.5.312",
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
@@ -1814,10 +1814,11 @@ function createProxyHandler<T>(
1814
1814
  endIndex: 10,
1815
1815
  });
1816
1816
 
1817
- const isAtBottomRef = useRef(stickToBottom);
1818
- const previousTotalCountRef = useRef(0);
1817
+ // --- State and Lock Management Refs ---
1818
+ const isLockedToBottomRef = useRef(stickToBottom);
1819
1819
  const isInitialMountRef = useRef(true);
1820
- const previousTotalHeightRef = useRef(0);
1820
+
1821
+ // Subscribe to shadow state changes for height updates
1821
1822
  const [shadowUpdateTrigger, setShadowUpdateTrigger] = useState(0);
1822
1823
 
1823
1824
  useEffect(() => {
@@ -1862,7 +1863,6 @@ function createProxyHandler<T>(
1862
1863
  shadowUpdateTrigger,
1863
1864
  ]);
1864
1865
 
1865
- console.log("height", totalHeight);
1866
1866
  const virtualState = useMemo(() => {
1867
1867
  const start = Math.max(0, range.startIndex);
1868
1868
  const end = Math.min(totalCount, range.endIndex);
@@ -1881,16 +1881,15 @@ function createProxyHandler<T>(
1881
1881
  const container = containerRef.current;
1882
1882
  if (!container) return;
1883
1883
 
1884
- const wasAtBottom = isAtBottomRef.current;
1885
- const listGrew = totalCount > previousTotalCountRef.current;
1886
- const heightGrew = totalHeight > previousTotalHeightRef.current;
1887
- previousTotalCountRef.current = totalCount;
1888
- previousTotalHeightRef.current = totalHeight;
1889
-
1890
1884
  const handleScroll = () => {
1891
1885
  const { scrollTop, clientHeight, scrollHeight } = container;
1892
- isAtBottomRef.current =
1893
- scrollHeight - scrollTop - clientHeight < 30;
1886
+
1887
+ // Determine if the user is at the bottom
1888
+ const isNowAtBottom =
1889
+ scrollHeight - scrollTop - clientHeight < 1;
1890
+
1891
+ // If the user scrolls up, unlock. If they scroll back down, re-lock.
1892
+ isLockedToBottomRef.current = isNowAtBottom;
1894
1893
 
1895
1894
  // Binary search for start index
1896
1895
  let low = 0,
@@ -1931,33 +1930,28 @@ function createProxyHandler<T>(
1931
1930
  passive: true,
1932
1931
  });
1933
1932
 
1934
- // Handle stick to bottom
1935
- if (stickToBottom) {
1933
+ // --- REFINED STICK-TO-BOTTOM LOGIC ---
1934
+ if (stickToBottom && isLockedToBottomRef.current) {
1935
+ // Use 'auto' for instant snap on first load, 'smooth' for subsequent updates.
1936
+ const behavior = isInitialMountRef.current
1937
+ ? "auto"
1938
+ : "smooth";
1939
+
1940
+ container.scrollTo({
1941
+ top: container.scrollHeight,
1942
+ behavior,
1943
+ });
1944
+ }
1945
+
1946
+ // After the first layout effect, it's no longer the initial mount.
1947
+ // queueMicrotask ensures this is set *after* the current render cycle.
1948
+ queueMicrotask(() => {
1936
1949
  if (isInitialMountRef.current) {
1937
- console.log(
1938
- "stickToBottom initial mount",
1939
- container.scrollHeight
1940
- );
1941
- container.scrollTo({
1942
- top: container.scrollHeight,
1943
- behavior: "auto",
1944
- });
1945
1950
  isInitialMountRef.current = false;
1946
- } else if (wasAtBottom && (listGrew || heightGrew)) {
1947
- console.log(
1948
- "stickToBottom wasAtBottom && listGrew",
1949
- container.scrollHeight
1950
- );
1951
- requestAnimationFrame(() => {
1952
- container.scrollTo({
1953
- top: container.scrollHeight,
1954
- behavior: "smooth",
1955
- });
1956
- });
1957
1951
  }
1958
- }
1959
- console.log("wasAtBottom && listGrew", wasAtBottom, listGrew);
1960
- // Run handleScroll once to set initial range
1952
+ });
1953
+
1954
+ // Run handleScroll once on setup to set initial range and lock status
1961
1955
  handleScroll();
1962
1956
 
1963
1957
  return () =>
@@ -2005,7 +1999,6 @@ function createProxyHandler<T>(
2005
1999
  },
2006
2000
  },
2007
2001
  };
2008
-
2009
2002
  return {
2010
2003
  virtualState,
2011
2004
  virtualizerProps,