cogsbox-state 0.5.320 → 0.5.321
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 +528 -515
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +82 -55
package/package.json
CHANGED
package/src/CogsState.tsx
CHANGED
|
@@ -1809,22 +1809,19 @@ function createProxyHandler<T>(
|
|
|
1809
1809
|
} = options;
|
|
1810
1810
|
|
|
1811
1811
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
1812
|
-
|
|
1813
|
-
const sourceArray = getGlobalStore().getNestedState(
|
|
1814
|
-
stateKey,
|
|
1815
|
-
path
|
|
1816
|
-
) as any[];
|
|
1817
|
-
const totalCount = sourceArray.length;
|
|
1818
|
-
|
|
1819
|
-
// Start at top, will adjust once container is measured
|
|
1820
1812
|
const [range, setRange] = useState({
|
|
1821
1813
|
startIndex: 0,
|
|
1822
1814
|
endIndex: 10,
|
|
1823
1815
|
});
|
|
1824
|
-
|
|
1825
1816
|
const isLockedToBottomRef = useRef(stickToBottom);
|
|
1826
1817
|
const [shadowUpdateTrigger, setShadowUpdateTrigger] = useState(0);
|
|
1827
|
-
const
|
|
1818
|
+
const hasScrolledToBottomRef = useRef(false);
|
|
1819
|
+
|
|
1820
|
+
const sourceArray = getGlobalStore().getNestedState(
|
|
1821
|
+
stateKey,
|
|
1822
|
+
path
|
|
1823
|
+
) as any[];
|
|
1824
|
+
const totalCount = sourceArray.length;
|
|
1828
1825
|
|
|
1829
1826
|
useEffect(() => {
|
|
1830
1827
|
const unsubscribe = getGlobalStore
|
|
@@ -1835,26 +1832,51 @@ function createProxyHandler<T>(
|
|
|
1835
1832
|
return unsubscribe;
|
|
1836
1833
|
}, [stateKey]);
|
|
1837
1834
|
|
|
1838
|
-
const { totalHeight, positions } =
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
pos[
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1835
|
+
const { totalHeight, positions, bottomItemsMeasured } =
|
|
1836
|
+
useMemo(() => {
|
|
1837
|
+
const shadowArray =
|
|
1838
|
+
getGlobalStore
|
|
1839
|
+
.getState()
|
|
1840
|
+
.getShadowMetadata(stateKey, path) || [];
|
|
1841
|
+
let height = 0;
|
|
1842
|
+
const pos: number[] = [];
|
|
1843
|
+
let bottomMeasuredCount = 0;
|
|
1844
|
+
|
|
1845
|
+
// Check how many of the last 20 items are measured
|
|
1846
|
+
const checkFromIndex = Math.max(0, totalCount - 20);
|
|
1847
|
+
|
|
1848
|
+
for (let i = 0; i < totalCount; i++) {
|
|
1849
|
+
pos[i] = height;
|
|
1850
|
+
const measuredHeight =
|
|
1851
|
+
shadowArray[i]?.virtualizer?.itemHeight;
|
|
1852
|
+
|
|
1853
|
+
if (measuredHeight) {
|
|
1854
|
+
height += measuredHeight;
|
|
1855
|
+
if (i >= checkFromIndex) {
|
|
1856
|
+
bottomMeasuredCount++;
|
|
1857
|
+
}
|
|
1858
|
+
} else {
|
|
1859
|
+
height += itemHeight;
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
// Bottom items are measured if we have measurements for the last 20 items
|
|
1864
|
+
const bottomReady =
|
|
1865
|
+
bottomMeasuredCount >=
|
|
1866
|
+
Math.min(20, totalCount - checkFromIndex);
|
|
1867
|
+
|
|
1868
|
+
return {
|
|
1869
|
+
totalHeight: height,
|
|
1870
|
+
positions: pos,
|
|
1871
|
+
bottomItemsMeasured: bottomReady,
|
|
1872
|
+
};
|
|
1873
|
+
}, [
|
|
1874
|
+
totalCount,
|
|
1875
|
+
stateKey,
|
|
1876
|
+
path.join("."),
|
|
1877
|
+
itemHeight,
|
|
1878
|
+
shadowUpdateTrigger,
|
|
1879
|
+
]);
|
|
1858
1880
|
|
|
1859
1881
|
const virtualState = useMemo(() => {
|
|
1860
1882
|
const start = Math.max(0, range.startIndex);
|
|
@@ -1910,32 +1932,31 @@ function createProxyHandler<T>(
|
|
|
1910
1932
|
passive: true,
|
|
1911
1933
|
});
|
|
1912
1934
|
|
|
1913
|
-
//
|
|
1935
|
+
// STICK TO BOTTOM LOGIC
|
|
1914
1936
|
if (
|
|
1915
1937
|
stickToBottom &&
|
|
1916
|
-
!
|
|
1917
|
-
totalCount > 0
|
|
1918
|
-
container.clientHeight > 0
|
|
1938
|
+
!hasScrolledToBottomRef.current &&
|
|
1939
|
+
totalCount > 0
|
|
1919
1940
|
) {
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1941
|
+
if (!bottomItemsMeasured) {
|
|
1942
|
+
// Step 1: Jump to near bottom to trigger rendering of bottom items
|
|
1943
|
+
console.log(
|
|
1944
|
+
"[VirtualView] Jumping to near bottom to trigger measurements"
|
|
1945
|
+
);
|
|
1946
|
+
const jumpPosition = Math.max(
|
|
1947
|
+
0,
|
|
1948
|
+
(totalCount - 30) * itemHeight
|
|
1949
|
+
);
|
|
1950
|
+
container.scrollTop = jumpPosition;
|
|
1951
|
+
} else {
|
|
1952
|
+
// Step 2: Bottom items are measured, now scroll to actual bottom
|
|
1953
|
+
console.log(
|
|
1954
|
+
"[VirtualView] Bottom items measured, scrolling to true bottom"
|
|
1955
|
+
);
|
|
1956
|
+
hasScrolledToBottomRef.current = true;
|
|
1957
|
+
container.scrollTop = container.scrollHeight;
|
|
1958
|
+
isLockedToBottomRef.current = true;
|
|
1959
|
+
}
|
|
1939
1960
|
}
|
|
1940
1961
|
|
|
1941
1962
|
updateVirtualRange();
|
|
@@ -1943,7 +1964,7 @@ function createProxyHandler<T>(
|
|
|
1943
1964
|
return () => {
|
|
1944
1965
|
container.removeEventListener("scroll", handleUserScroll);
|
|
1945
1966
|
};
|
|
1946
|
-
}, [totalCount, positions, stickToBottom,
|
|
1967
|
+
}, [totalCount, positions, stickToBottom, bottomItemsMeasured]);
|
|
1947
1968
|
|
|
1948
1969
|
const scrollToBottom = useCallback(
|
|
1949
1970
|
(behavior: ScrollBehavior = "smooth") => {
|
|
@@ -1974,7 +1995,13 @@ function createProxyHandler<T>(
|
|
|
1974
1995
|
const virtualizerProps = {
|
|
1975
1996
|
outer: {
|
|
1976
1997
|
ref: containerRef,
|
|
1977
|
-
style: {
|
|
1998
|
+
style: {
|
|
1999
|
+
overflowY: "auto" as const,
|
|
2000
|
+
height: "100%",
|
|
2001
|
+
overflowAnchor: stickToBottom
|
|
2002
|
+
? ("auto" as const)
|
|
2003
|
+
: ("none" as const),
|
|
2004
|
+
},
|
|
1978
2005
|
},
|
|
1979
2006
|
inner: {
|
|
1980
2007
|
style: {
|