cogsbox-state 0.5.285 → 0.5.287
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.d.ts +1 -1
- package/dist/CogsState.jsx +489 -496
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +54 -69
package/package.json
CHANGED
package/src/CogsState.tsx
CHANGED
|
@@ -42,7 +42,7 @@ import useMeasure from "react-use-measure";
|
|
|
42
42
|
type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
43
43
|
|
|
44
44
|
export type VirtualViewOptions = {
|
|
45
|
-
itemHeight
|
|
45
|
+
itemHeight?: number;
|
|
46
46
|
overscan?: number;
|
|
47
47
|
stickToBottom?: boolean;
|
|
48
48
|
};
|
|
@@ -1466,6 +1466,8 @@ function createProxyHandler<T>(
|
|
|
1466
1466
|
if (localStorage.getItem(storageKey)) {
|
|
1467
1467
|
localStorage.removeItem(storageKey);
|
|
1468
1468
|
}
|
|
1469
|
+
|
|
1470
|
+
console.log("udpating intial State", stateKey, newState);
|
|
1469
1471
|
startTransition(() => {
|
|
1470
1472
|
updateInitialStateGlobal(stateKey, newState);
|
|
1471
1473
|
getGlobalStore.getState().initializeShadowState(stateKey, newState);
|
|
@@ -1802,7 +1804,7 @@ function createProxyHandler<T>(
|
|
|
1802
1804
|
options: VirtualViewOptions
|
|
1803
1805
|
): VirtualStateObjectResult<any[]> => {
|
|
1804
1806
|
const {
|
|
1805
|
-
itemHeight = 50, //
|
|
1807
|
+
itemHeight = 50, // Default height for unmeasured items
|
|
1806
1808
|
overscan = 5,
|
|
1807
1809
|
stickToBottom = false,
|
|
1808
1810
|
} = options;
|
|
@@ -1813,34 +1815,7 @@ function createProxyHandler<T>(
|
|
|
1813
1815
|
endIndex: 10,
|
|
1814
1816
|
});
|
|
1815
1817
|
|
|
1816
|
-
//
|
|
1817
|
-
const getItemHeight = useCallback(
|
|
1818
|
-
(index: number) => {
|
|
1819
|
-
const metadata = getGlobalStore
|
|
1820
|
-
.getState()
|
|
1821
|
-
.getShadowMetadata(stateKey, [...path, index.toString()]);
|
|
1822
|
-
return metadata?.virtualizer?.itemHeight || itemHeight;
|
|
1823
|
-
},
|
|
1824
|
-
[itemHeight]
|
|
1825
|
-
);
|
|
1826
|
-
|
|
1827
|
-
// Calculate total height and item positions
|
|
1828
|
-
const calculateHeights = useCallback(() => {
|
|
1829
|
-
const sourceArray = getGlobalStore
|
|
1830
|
-
.getState()
|
|
1831
|
-
.getNestedState(stateKey, path) as any[];
|
|
1832
|
-
|
|
1833
|
-
let totalHeight = 0;
|
|
1834
|
-
const positions: number[] = [];
|
|
1835
|
-
|
|
1836
|
-
for (let i = 0; i < sourceArray.length; i++) {
|
|
1837
|
-
positions[i] = totalHeight;
|
|
1838
|
-
totalHeight += getItemHeight(i);
|
|
1839
|
-
}
|
|
1840
|
-
|
|
1841
|
-
return { totalHeight, positions };
|
|
1842
|
-
}, [getItemHeight]);
|
|
1843
|
-
|
|
1818
|
+
// --- State Tracking Refs for stickToBottom ---
|
|
1844
1819
|
const isAtBottomRef = useRef(stickToBottom);
|
|
1845
1820
|
const previousTotalCountRef = useRef(0);
|
|
1846
1821
|
const isInitialMountRef = useRef(true);
|
|
@@ -1851,6 +1826,28 @@ function createProxyHandler<T>(
|
|
|
1851
1826
|
) as any[];
|
|
1852
1827
|
const totalCount = sourceArray.length;
|
|
1853
1828
|
|
|
1829
|
+
// Helper to get an item's measured height or the default
|
|
1830
|
+
const getItemHeight = useCallback(
|
|
1831
|
+
(index: number): number => {
|
|
1832
|
+
const metadata = getGlobalStore
|
|
1833
|
+
.getState()
|
|
1834
|
+
.getShadowMetadata(stateKey, [...path, index.toString()]);
|
|
1835
|
+
return metadata?.virtualizer?.itemHeight || itemHeight;
|
|
1836
|
+
},
|
|
1837
|
+
[itemHeight, stateKey, path]
|
|
1838
|
+
);
|
|
1839
|
+
|
|
1840
|
+
// Pre-calculate total height and the top offset of each item
|
|
1841
|
+
const { totalHeight, positions } = useMemo(() => {
|
|
1842
|
+
let currentHeight = 0;
|
|
1843
|
+
const pos: number[] = [];
|
|
1844
|
+
for (let i = 0; i < totalCount; i++) {
|
|
1845
|
+
pos[i] = currentHeight;
|
|
1846
|
+
currentHeight += getItemHeight(i);
|
|
1847
|
+
}
|
|
1848
|
+
return { totalHeight: currentHeight, positions: pos };
|
|
1849
|
+
}, [totalCount, getItemHeight]);
|
|
1850
|
+
|
|
1854
1851
|
const virtualState = useMemo(() => {
|
|
1855
1852
|
const start = Math.max(0, range.startIndex);
|
|
1856
1853
|
const end = Math.min(totalCount, range.endIndex);
|
|
@@ -1872,44 +1869,39 @@ function createProxyHandler<T>(
|
|
|
1872
1869
|
const wasAtBottom = isAtBottomRef.current;
|
|
1873
1870
|
const listGrew = totalCount > previousTotalCountRef.current;
|
|
1874
1871
|
previousTotalCountRef.current = totalCount;
|
|
1875
|
-
|
|
1876
|
-
const { totalHeight, positions } = calculateHeights();
|
|
1877
|
-
|
|
1878
1872
|
const handleScroll = () => {
|
|
1879
1873
|
const { scrollTop, clientHeight, scrollHeight } = container;
|
|
1880
1874
|
isAtBottomRef.current =
|
|
1881
1875
|
scrollHeight - scrollTop - clientHeight < 10;
|
|
1882
1876
|
|
|
1883
|
-
// Find start index
|
|
1884
|
-
let
|
|
1885
|
-
let
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
start = mid + 1;
|
|
1890
|
-
} else {
|
|
1891
|
-
end = mid;
|
|
1877
|
+
// Find the start index by searching for the first item in the viewport
|
|
1878
|
+
let startIndex = 0;
|
|
1879
|
+
for (let i = 0; i < positions.length; i++) {
|
|
1880
|
+
if (positions[i]! >= scrollTop) {
|
|
1881
|
+
startIndex = i;
|
|
1882
|
+
break;
|
|
1892
1883
|
}
|
|
1893
1884
|
}
|
|
1894
|
-
start = Math.max(0, start - overscan);
|
|
1895
1885
|
|
|
1896
|
-
// Find end index
|
|
1897
|
-
|
|
1898
|
-
let endIndex = start;
|
|
1886
|
+
// Find the end index by seeing how many items fit in the viewport
|
|
1887
|
+
let endIndex = startIndex;
|
|
1899
1888
|
while (
|
|
1900
|
-
endIndex <
|
|
1901
|
-
positions[endIndex]! <
|
|
1889
|
+
endIndex < totalCount &&
|
|
1890
|
+
positions[endIndex]! < scrollTop + clientHeight
|
|
1902
1891
|
) {
|
|
1903
1892
|
endIndex++;
|
|
1904
1893
|
}
|
|
1894
|
+
|
|
1895
|
+
// Apply overscan
|
|
1896
|
+
startIndex = Math.max(0, startIndex - overscan);
|
|
1905
1897
|
endIndex = Math.min(totalCount, endIndex + overscan);
|
|
1906
1898
|
|
|
1907
1899
|
setRange((prevRange) => {
|
|
1908
1900
|
if (
|
|
1909
|
-
prevRange.startIndex !==
|
|
1901
|
+
prevRange.startIndex !== startIndex ||
|
|
1910
1902
|
prevRange.endIndex !== endIndex
|
|
1911
1903
|
) {
|
|
1912
|
-
return { startIndex
|
|
1904
|
+
return { startIndex, endIndex };
|
|
1913
1905
|
}
|
|
1914
1906
|
return prevRange;
|
|
1915
1907
|
});
|
|
@@ -1919,6 +1911,7 @@ function createProxyHandler<T>(
|
|
|
1919
1911
|
passive: true,
|
|
1920
1912
|
});
|
|
1921
1913
|
|
|
1914
|
+
// Logic to keep the view scrolled to the bottom
|
|
1922
1915
|
if (stickToBottom) {
|
|
1923
1916
|
if (isInitialMountRef.current) {
|
|
1924
1917
|
container.scrollTo({
|
|
@@ -1936,11 +1929,11 @@ function createProxyHandler<T>(
|
|
|
1936
1929
|
}
|
|
1937
1930
|
|
|
1938
1931
|
isInitialMountRef.current = false;
|
|
1939
|
-
handleScroll();
|
|
1932
|
+
handleScroll(); // Initial calculation
|
|
1940
1933
|
|
|
1941
1934
|
return () =>
|
|
1942
1935
|
container.removeEventListener("scroll", handleScroll);
|
|
1943
|
-
}, [totalCount,
|
|
1936
|
+
}, [totalCount, overscan, stickToBottom, positions]);
|
|
1944
1937
|
|
|
1945
1938
|
const scrollToBottom = useCallback(
|
|
1946
1939
|
(behavior: ScrollBehavior = "smooth") => {
|
|
@@ -1956,45 +1949,37 @@ function createProxyHandler<T>(
|
|
|
1956
1949
|
|
|
1957
1950
|
const scrollToIndex = useCallback(
|
|
1958
1951
|
(index: number, behavior: ScrollBehavior = "smooth") => {
|
|
1959
|
-
if (containerRef.current) {
|
|
1960
|
-
const { positions } = calculateHeights();
|
|
1952
|
+
if (containerRef.current && positions[index] !== undefined) {
|
|
1961
1953
|
containerRef.current.scrollTo({
|
|
1962
|
-
top: positions[index]
|
|
1954
|
+
top: positions[index],
|
|
1963
1955
|
behavior,
|
|
1964
1956
|
});
|
|
1965
1957
|
}
|
|
1966
1958
|
},
|
|
1967
|
-
[
|
|
1959
|
+
[positions] // Depends on the calculated positions
|
|
1968
1960
|
);
|
|
1969
1961
|
|
|
1970
|
-
// Calculate actual heights for rendering
|
|
1971
|
-
const {
|
|
1972
|
-
totalHeight: totalHeightForRender,
|
|
1973
|
-
positions: positionsForRender,
|
|
1974
|
-
} = calculateHeights();
|
|
1975
|
-
const offsetY = positionsForRender[range.startIndex] || 0;
|
|
1976
|
-
|
|
1977
1962
|
const virtualizerProps = {
|
|
1978
1963
|
outer: {
|
|
1979
1964
|
ref: containerRef,
|
|
1980
|
-
style: { overflowY: "auto", height: "100%" }
|
|
1965
|
+
style: { overflowY: "auto", height: "100%" },
|
|
1981
1966
|
},
|
|
1982
1967
|
inner: {
|
|
1983
1968
|
style: {
|
|
1984
|
-
height: `${
|
|
1969
|
+
height: `${totalHeight}px`,
|
|
1985
1970
|
position: "relative",
|
|
1986
|
-
}
|
|
1971
|
+
},
|
|
1987
1972
|
},
|
|
1988
1973
|
list: {
|
|
1989
1974
|
style: {
|
|
1990
|
-
transform: `translateY(${
|
|
1991
|
-
}
|
|
1975
|
+
transform: `translateY(${positions[range.startIndex] || 0}px)`,
|
|
1976
|
+
},
|
|
1992
1977
|
},
|
|
1993
1978
|
};
|
|
1994
1979
|
|
|
1995
1980
|
return {
|
|
1996
1981
|
virtualState,
|
|
1997
|
-
virtualizerProps,
|
|
1982
|
+
virtualizerProps: virtualizerProps as any,
|
|
1998
1983
|
scrollToBottom,
|
|
1999
1984
|
scrollToIndex,
|
|
2000
1985
|
};
|