cogsbox-state 0.5.411 → 0.5.413
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 +582 -576
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +38 -33
package/package.json
CHANGED
package/src/CogsState.tsx
CHANGED
|
@@ -1821,8 +1821,9 @@ function createProxyHandler<T>(
|
|
|
1821
1821
|
endIndex: 10,
|
|
1822
1822
|
});
|
|
1823
1823
|
const [shadowUpdateTrigger, setShadowUpdateTrigger] = useState(0);
|
|
1824
|
-
const wasAtBottomRef = useRef(
|
|
1824
|
+
const wasAtBottomRef = useRef(false);
|
|
1825
1825
|
const previousCountRef = useRef(0);
|
|
1826
|
+
const hasInitializedRef = useRef(false); // Track if we've done initial scroll
|
|
1826
1827
|
|
|
1827
1828
|
// Subscribe to shadow state updates
|
|
1828
1829
|
useEffect(() => {
|
|
@@ -1901,52 +1902,60 @@ function createProxyHandler<T>(
|
|
|
1901
1902
|
return false;
|
|
1902
1903
|
}, [stateKey, path, totalCount]);
|
|
1903
1904
|
|
|
1904
|
-
// Handle new items
|
|
1905
|
+
// Handle ONLY new items - not height changes
|
|
1905
1906
|
useEffect(() => {
|
|
1906
1907
|
if (!stickToBottom || totalCount === 0) return;
|
|
1907
1908
|
|
|
1908
1909
|
const hasNewItems = totalCount > previousCountRef.current;
|
|
1909
|
-
const isInitialLoad =
|
|
1910
|
-
previousCountRef.current === 0 && totalCount > 0;
|
|
1911
1910
|
|
|
1912
|
-
|
|
1913
|
-
|
|
1911
|
+
// Initial load
|
|
1912
|
+
if (
|
|
1913
|
+
previousCountRef.current === 0 &&
|
|
1914
|
+
totalCount > 0 &&
|
|
1915
|
+
!hasInitializedRef.current
|
|
1916
|
+
) {
|
|
1917
|
+
hasInitializedRef.current = true;
|
|
1914
1918
|
const visibleCount = Math.ceil(
|
|
1915
|
-
containerRef.current?.clientHeight ||
|
|
1919
|
+
(containerRef.current?.clientHeight || 600) / itemHeight
|
|
1916
1920
|
);
|
|
1917
|
-
|
|
1921
|
+
setRange({
|
|
1918
1922
|
startIndex: Math.max(
|
|
1919
1923
|
0,
|
|
1920
1924
|
totalCount - visibleCount - overscan
|
|
1921
1925
|
),
|
|
1922
1926
|
endIndex: totalCount,
|
|
1923
|
-
};
|
|
1924
|
-
|
|
1925
|
-
setRange(newRange);
|
|
1927
|
+
});
|
|
1926
1928
|
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
const scrolled = scrollToLastItem();
|
|
1930
|
-
if (!scrolled && containerRef.current) {
|
|
1931
|
-
// Fallback if ref not available yet
|
|
1929
|
+
setTimeout(() => {
|
|
1930
|
+
if (containerRef.current) {
|
|
1932
1931
|
containerRef.current.scrollTop =
|
|
1933
1932
|
containerRef.current.scrollHeight;
|
|
1933
|
+
wasAtBottomRef.current = true;
|
|
1934
1934
|
}
|
|
1935
|
-
},
|
|
1935
|
+
}, 100);
|
|
1936
|
+
}
|
|
1937
|
+
// New items added AFTER initial load
|
|
1938
|
+
else if (hasNewItems && wasAtBottomRef.current) {
|
|
1939
|
+
const visibleCount = Math.ceil(
|
|
1940
|
+
(containerRef.current?.clientHeight || 600) / itemHeight
|
|
1941
|
+
);
|
|
1942
|
+
const newRange = {
|
|
1943
|
+
startIndex: Math.max(
|
|
1944
|
+
0,
|
|
1945
|
+
totalCount - visibleCount - overscan
|
|
1946
|
+
),
|
|
1947
|
+
endIndex: totalCount,
|
|
1948
|
+
};
|
|
1936
1949
|
|
|
1937
|
-
|
|
1950
|
+
setRange(newRange);
|
|
1938
1951
|
|
|
1939
|
-
|
|
1952
|
+
setTimeout(() => {
|
|
1953
|
+
scrollToLastItem();
|
|
1954
|
+
}, 50);
|
|
1940
1955
|
}
|
|
1941
1956
|
|
|
1942
1957
|
previousCountRef.current = totalCount;
|
|
1943
|
-
}, [
|
|
1944
|
-
totalCount,
|
|
1945
|
-
stickToBottom,
|
|
1946
|
-
itemHeight,
|
|
1947
|
-
overscan,
|
|
1948
|
-
scrollToLastItem,
|
|
1949
|
-
]);
|
|
1958
|
+
}, [totalCount]); // ONLY depend on totalCount, not positions!
|
|
1950
1959
|
|
|
1951
1960
|
// Handle scroll events
|
|
1952
1961
|
useEffect(() => {
|
|
@@ -1958,7 +1967,7 @@ function createProxyHandler<T>(
|
|
|
1958
1967
|
const distanceFromBottom =
|
|
1959
1968
|
scrollHeight - scrollTop - clientHeight;
|
|
1960
1969
|
|
|
1961
|
-
// Track if we're at bottom
|
|
1970
|
+
// Track if we're at bottom
|
|
1962
1971
|
wasAtBottomRef.current = distanceFromBottom < 100;
|
|
1963
1972
|
|
|
1964
1973
|
// Update visible range based on scroll position
|
|
@@ -1989,17 +1998,13 @@ function createProxyHandler<T>(
|
|
|
1989
1998
|
passive: true,
|
|
1990
1999
|
});
|
|
1991
2000
|
|
|
1992
|
-
//
|
|
1993
|
-
if (stickToBottom && totalCount > 0) {
|
|
1994
|
-
// For initial load, jump to bottom
|
|
1995
|
-
container.scrollTop = container.scrollHeight;
|
|
1996
|
-
}
|
|
2001
|
+
// Just calculate visible range, no scrolling
|
|
1997
2002
|
handleScroll();
|
|
1998
2003
|
|
|
1999
2004
|
return () => {
|
|
2000
2005
|
container.removeEventListener("scroll", handleScroll);
|
|
2001
2006
|
};
|
|
2002
|
-
}, [positions, totalCount, itemHeight, overscan
|
|
2007
|
+
}, [positions, totalCount, itemHeight, overscan]);
|
|
2003
2008
|
|
|
2004
2009
|
const scrollToBottom = useCallback(() => {
|
|
2005
2010
|
wasAtBottomRef.current = true;
|