cogsbox-state 0.5.299 → 0.5.300

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.299",
3
+ "version": "0.5.300",
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
@@ -1880,16 +1880,24 @@ function createProxyHandler<T>(
1880
1880
  const container = containerRef.current;
1881
1881
  if (!container) return;
1882
1882
 
1883
- const wasAtBottom = isAtBottomRef.current;
1884
1883
  const listGrew = totalCount > previousTotalCountRef.current;
1884
+
1885
+ // --- THE FIX for BOTH initial load and new entries ---
1886
+ // We capture the scroll position *before* we do anything else.
1887
+ // We also check if we are VERY close to the bottom. This will be true
1888
+ // on initial load (0 scrollHeight, 0 scrollTop) and when user is at the end.
1889
+ const wasAtBottom =
1890
+ container.scrollHeight -
1891
+ container.scrollTop -
1892
+ container.clientHeight <
1893
+ 5;
1894
+
1895
+ // Now we update the ref for the *next* render cycle.
1885
1896
  previousTotalCountRef.current = totalCount;
1886
1897
 
1887
1898
  const handleScroll = () => {
1899
+ // ... (binary search logic to setRange is the same) ...
1888
1900
  const { scrollTop, clientHeight, scrollHeight } = container;
1889
- isAtBottomRef.current =
1890
- scrollHeight - scrollTop - clientHeight < 5; // Use a small tolerance
1891
-
1892
- // ... (binary search logic to setRange) ...
1893
1901
  let search = (list: number[], value: number) => {
1894
1902
  let low = 0;
1895
1903
  let high = list.length - 1;
@@ -1927,26 +1935,23 @@ function createProxyHandler<T>(
1927
1935
  container.addEventListener("scroll", handleScroll, {
1928
1936
  passive: true,
1929
1937
  });
1930
- handleScroll(); // Run once to set initial view
1931
-
1932
- // --- THE SIMPLE FIX ---
1933
- // We check the flags *after* handleScroll has updated them.
1934
- if (stickToBottom) {
1935
- if (isInitialMountRef.current) {
1936
- // On first load, always go to the bottom.
1937
- container.scrollTo({
1938
- top: container.scrollHeight,
1939
- behavior: "auto",
1940
- });
1941
- isInitialMountRef.current = false;
1942
- } else if (listGrew && wasAtBottom) {
1943
- // If a new item was added AND we were already at the bottom,
1944
- // scroll to the new bottom.
1945
- container.scrollTo({
1946
- top: container.scrollHeight,
1947
- behavior: "auto",
1948
- });
1949
- }
1938
+ handleScroll();
1939
+
1940
+ // This single block now handles all cases.
1941
+ if (
1942
+ stickToBottom &&
1943
+ (listGrew || isInitialMountRef.current) &&
1944
+ wasAtBottom
1945
+ ) {
1946
+ container.scrollTo({
1947
+ top: container.scrollHeight,
1948
+ behavior: "auto",
1949
+ });
1950
+ }
1951
+
1952
+ // We only set this to false after the first correct layout has been established.
1953
+ if (positions.length > 0) {
1954
+ isInitialMountRef.current = false;
1950
1955
  }
1951
1956
 
1952
1957
  return () =>