cogsbox-state 0.5.361 → 0.5.364
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 +525 -525
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +31 -17
package/package.json
CHANGED
package/src/CogsState.tsx
CHANGED
|
@@ -1817,6 +1817,7 @@ function createProxyHandler<T>(
|
|
|
1817
1817
|
const isLockedToBottomRef = useRef(stickToBottom);
|
|
1818
1818
|
const isAutoScrolling = useRef(false);
|
|
1819
1819
|
const prevTotalCountRef = useRef(0);
|
|
1820
|
+
const prevDepsRef = useRef(dependencies);
|
|
1820
1821
|
|
|
1821
1822
|
const [shadowUpdateTrigger, setShadowUpdateTrigger] = useState(0);
|
|
1822
1823
|
|
|
@@ -1870,10 +1871,23 @@ function createProxyHandler<T>(
|
|
|
1870
1871
|
});
|
|
1871
1872
|
}, [range.startIndex, range.endIndex, sourceArray, totalCount]);
|
|
1872
1873
|
|
|
1873
|
-
// --- PHASE 1: Detect
|
|
1874
|
+
// --- PHASE 1: Detect change & SET THE RANGE ---
|
|
1875
|
+
// This effect's ONLY job is to decide if we need to auto-scroll and then set the range to the end.
|
|
1874
1876
|
useLayoutEffect(() => {
|
|
1875
1877
|
const hasNewItems = totalCount > prevTotalCountRef.current;
|
|
1876
|
-
|
|
1878
|
+
const depsChanged = !isDeepEqual(
|
|
1879
|
+
dependencies,
|
|
1880
|
+
prevDepsRef.current
|
|
1881
|
+
);
|
|
1882
|
+
|
|
1883
|
+
if (depsChanged) {
|
|
1884
|
+
isLockedToBottomRef.current = stickToBottom;
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
if (
|
|
1888
|
+
isLockedToBottomRef.current &&
|
|
1889
|
+
(hasNewItems || depsChanged)
|
|
1890
|
+
) {
|
|
1877
1891
|
console.log(
|
|
1878
1892
|
"PHASE 1: Auto-scroll needed. Setting range to render the last item."
|
|
1879
1893
|
);
|
|
@@ -1882,25 +1896,29 @@ function createProxyHandler<T>(
|
|
|
1882
1896
|
endIndex: totalCount,
|
|
1883
1897
|
});
|
|
1884
1898
|
}
|
|
1899
|
+
|
|
1885
1900
|
prevTotalCountRef.current = totalCount;
|
|
1886
|
-
|
|
1901
|
+
prevDepsRef.current = dependencies;
|
|
1902
|
+
}, [totalCount, ...dependencies]);
|
|
1887
1903
|
|
|
1888
|
-
// --- PHASE 2: Wait for measurement
|
|
1904
|
+
// --- PHASE 2: Wait for measurement & SCROLL ---
|
|
1905
|
+
// This effect's ONLY job is to run YOUR loop after Phase 1 is complete.
|
|
1889
1906
|
useLayoutEffect(() => {
|
|
1890
1907
|
const container = containerRef.current;
|
|
1891
|
-
const
|
|
1908
|
+
const isRangeSetToEnd =
|
|
1892
1909
|
range.endIndex === totalCount && totalCount > 0;
|
|
1893
1910
|
|
|
1911
|
+
// We only start the loop if the range is correctly set to the end and we are locked.
|
|
1894
1912
|
if (
|
|
1895
1913
|
!container ||
|
|
1896
1914
|
!isLockedToBottomRef.current ||
|
|
1897
|
-
!
|
|
1915
|
+
!isRangeSetToEnd
|
|
1898
1916
|
) {
|
|
1899
1917
|
return;
|
|
1900
1918
|
}
|
|
1901
1919
|
|
|
1902
1920
|
console.log(
|
|
1903
|
-
"PHASE 2: Range is
|
|
1921
|
+
"PHASE 2: Range is set to the end. Starting the measurement loop."
|
|
1904
1922
|
);
|
|
1905
1923
|
let loopCount = 0;
|
|
1906
1924
|
const intervalId = setInterval(() => {
|
|
@@ -1927,10 +1945,11 @@ function createProxyHandler<T>(
|
|
|
1927
1945
|
top: container.scrollHeight,
|
|
1928
1946
|
behavior: "smooth",
|
|
1929
1947
|
});
|
|
1948
|
+
// Give the animation time to finish before unsetting the flag
|
|
1930
1949
|
setTimeout(() => {
|
|
1931
1950
|
isAutoScrolling.current = false;
|
|
1932
1951
|
}, 1000);
|
|
1933
|
-
} else if (loopCount >
|
|
1952
|
+
} else if (loopCount > 30) {
|
|
1934
1953
|
console.error(
|
|
1935
1954
|
"LOOP TIMEOUT: Last item was never measured. Stopping loop."
|
|
1936
1955
|
);
|
|
@@ -1941,18 +1960,13 @@ function createProxyHandler<T>(
|
|
|
1941
1960
|
}, 100);
|
|
1942
1961
|
|
|
1943
1962
|
return () => clearInterval(intervalId);
|
|
1944
|
-
}, [range
|
|
1963
|
+
}, [range]); // This effect is triggered by the `setRange` call in Phase 1.
|
|
1945
1964
|
|
|
1946
|
-
// --- PHASE 3: Handle User
|
|
1965
|
+
// --- PHASE 3: Handle User Scrolling ---
|
|
1947
1966
|
useEffect(() => {
|
|
1948
1967
|
const container = containerRef.current;
|
|
1949
1968
|
if (!container) return;
|
|
1950
1969
|
|
|
1951
|
-
console.log(
|
|
1952
|
-
"DEPENDENCY CHANGE: Resetting scroll lock and initial view."
|
|
1953
|
-
);
|
|
1954
|
-
isLockedToBottomRef.current = stickToBottom;
|
|
1955
|
-
|
|
1956
1970
|
const updateVirtualRange = () => {
|
|
1957
1971
|
const { scrollTop, clientHeight } = container;
|
|
1958
1972
|
let low = 0,
|
|
@@ -1993,11 +2007,11 @@ function createProxyHandler<T>(
|
|
|
1993
2007
|
container.addEventListener("scroll", handleUserScroll, {
|
|
1994
2008
|
passive: true,
|
|
1995
2009
|
});
|
|
1996
|
-
updateVirtualRange();
|
|
2010
|
+
updateVirtualRange(); // Always run to set the initial view
|
|
1997
2011
|
|
|
1998
2012
|
return () =>
|
|
1999
2013
|
container.removeEventListener("scroll", handleUserScroll);
|
|
2000
|
-
}, [...dependencies]);
|
|
2014
|
+
}, [totalCount, positions, ...dependencies]);
|
|
2001
2015
|
|
|
2002
2016
|
const scrollToBottom = useCallback(
|
|
2003
2017
|
(behavior: ScrollBehavior = "smooth") => {
|