cogsbox-state 0.5.287 → 0.5.289
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 +571 -584
- package/dist/CogsState.jsx.map +1 -1
- package/package.json +1 -1
- package/src/CogsState.tsx +43 -62
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,8 +1466,6 @@ 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);
|
|
1471
1469
|
startTransition(() => {
|
|
1472
1470
|
updateInitialStateGlobal(stateKey, newState);
|
|
1473
1471
|
getGlobalStore.getState().initializeShadowState(stateKey, newState);
|
|
@@ -1560,7 +1558,10 @@ function createProxyHandler<T>(
|
|
|
1560
1558
|
"_stateKey",
|
|
1561
1559
|
"getComponents",
|
|
1562
1560
|
]);
|
|
1561
|
+
|
|
1562
|
+
console.log("prop", target, path, prop);
|
|
1563
1563
|
if (
|
|
1564
|
+
prop &&
|
|
1564
1565
|
prop !== "then" &&
|
|
1565
1566
|
!prop.startsWith("$") &&
|
|
1566
1567
|
prop !== "stateMapNoRender" &&
|
|
@@ -1804,7 +1805,7 @@ function createProxyHandler<T>(
|
|
|
1804
1805
|
options: VirtualViewOptions
|
|
1805
1806
|
): VirtualStateObjectResult<any[]> => {
|
|
1806
1807
|
const {
|
|
1807
|
-
itemHeight
|
|
1808
|
+
itemHeight,
|
|
1808
1809
|
overscan = 5,
|
|
1809
1810
|
stickToBottom = false,
|
|
1810
1811
|
} = options;
|
|
@@ -1814,10 +1815,16 @@ function createProxyHandler<T>(
|
|
|
1814
1815
|
startIndex: 0,
|
|
1815
1816
|
endIndex: 10,
|
|
1816
1817
|
});
|
|
1817
|
-
|
|
1818
|
-
//
|
|
1818
|
+
// const getItemHeight = useCallback((index: number) => {
|
|
1819
|
+
// const metadata = getGlobalStore
|
|
1820
|
+
// .getState()
|
|
1821
|
+
// .getShadowMetadata(stateKey, [...path, index.toString()]);
|
|
1822
|
+
// return metadata?.virtualizer?.itemHeight || options.itemHeight;
|
|
1823
|
+
// }, []);
|
|
1824
|
+
// --- State Tracking Refs ---
|
|
1819
1825
|
const isAtBottomRef = useRef(stickToBottom);
|
|
1820
1826
|
const previousTotalCountRef = useRef(0);
|
|
1827
|
+
// NEW: Ref to explicitly track if this is the component's first render cycle.
|
|
1821
1828
|
const isInitialMountRef = useRef(true);
|
|
1822
1829
|
|
|
1823
1830
|
const sourceArray = getGlobalStore().getNestedState(
|
|
@@ -1826,28 +1833,6 @@ function createProxyHandler<T>(
|
|
|
1826
1833
|
) as any[];
|
|
1827
1834
|
const totalCount = sourceArray.length;
|
|
1828
1835
|
|
|
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
|
-
|
|
1851
1836
|
const virtualState = useMemo(() => {
|
|
1852
1837
|
const start = Math.max(0, range.startIndex);
|
|
1853
1838
|
const end = Math.min(totalCount, range.endIndex);
|
|
@@ -1869,39 +1854,26 @@ function createProxyHandler<T>(
|
|
|
1869
1854
|
const wasAtBottom = isAtBottomRef.current;
|
|
1870
1855
|
const listGrew = totalCount > previousTotalCountRef.current;
|
|
1871
1856
|
previousTotalCountRef.current = totalCount;
|
|
1857
|
+
|
|
1872
1858
|
const handleScroll = () => {
|
|
1873
1859
|
const { scrollTop, clientHeight, scrollHeight } = container;
|
|
1874
1860
|
isAtBottomRef.current =
|
|
1875
1861
|
scrollHeight - scrollTop - clientHeight < 10;
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
// Find the end index by seeing how many items fit in the viewport
|
|
1887
|
-
let endIndex = startIndex;
|
|
1888
|
-
while (
|
|
1889
|
-
endIndex < totalCount &&
|
|
1890
|
-
positions[endIndex]! < scrollTop + clientHeight
|
|
1891
|
-
) {
|
|
1892
|
-
endIndex++;
|
|
1893
|
-
}
|
|
1894
|
-
|
|
1895
|
-
// Apply overscan
|
|
1896
|
-
startIndex = Math.max(0, startIndex - overscan);
|
|
1897
|
-
endIndex = Math.min(totalCount, endIndex + overscan);
|
|
1898
|
-
|
|
1862
|
+
const start = Math.max(
|
|
1863
|
+
0,
|
|
1864
|
+
Math.floor(scrollTop / itemHeight) - overscan
|
|
1865
|
+
);
|
|
1866
|
+
const end = Math.min(
|
|
1867
|
+
totalCount,
|
|
1868
|
+
Math.ceil((scrollTop + clientHeight) / itemHeight) +
|
|
1869
|
+
overscan
|
|
1870
|
+
);
|
|
1899
1871
|
setRange((prevRange) => {
|
|
1900
1872
|
if (
|
|
1901
|
-
prevRange.startIndex !==
|
|
1902
|
-
prevRange.endIndex !==
|
|
1873
|
+
prevRange.startIndex !== start ||
|
|
1874
|
+
prevRange.endIndex !== end
|
|
1903
1875
|
) {
|
|
1904
|
-
return { startIndex, endIndex };
|
|
1876
|
+
return { startIndex: start, endIndex: end };
|
|
1905
1877
|
}
|
|
1906
1878
|
return prevRange;
|
|
1907
1879
|
});
|
|
@@ -1911,14 +1883,19 @@ function createProxyHandler<T>(
|
|
|
1911
1883
|
passive: true,
|
|
1912
1884
|
});
|
|
1913
1885
|
|
|
1914
|
-
//
|
|
1886
|
+
// --- THE CORRECTED DECISION LOGIC ---
|
|
1915
1887
|
if (stickToBottom) {
|
|
1916
1888
|
if (isInitialMountRef.current) {
|
|
1889
|
+
// SCENARIO 1: First render of the component.
|
|
1890
|
+
// Go to the bottom unconditionally. Use `auto` scroll for an instant jump.
|
|
1917
1891
|
container.scrollTo({
|
|
1918
1892
|
top: container.scrollHeight,
|
|
1919
1893
|
behavior: "auto",
|
|
1920
1894
|
});
|
|
1921
1895
|
} else if (wasAtBottom && listGrew) {
|
|
1896
|
+
// SCENARIO 2: Subsequent renders (new messages arrive).
|
|
1897
|
+
// Only scroll if the user was already at the bottom.
|
|
1898
|
+
// Use `smooth` for a nice animated scroll for new messages.
|
|
1922
1899
|
requestAnimationFrame(() => {
|
|
1923
1900
|
container.scrollTo({
|
|
1924
1901
|
top: container.scrollHeight,
|
|
@@ -1928,12 +1905,15 @@ function createProxyHandler<T>(
|
|
|
1928
1905
|
}
|
|
1929
1906
|
}
|
|
1930
1907
|
|
|
1908
|
+
// After the logic runs, it's no longer the initial mount.
|
|
1931
1909
|
isInitialMountRef.current = false;
|
|
1932
|
-
|
|
1910
|
+
|
|
1911
|
+
// Always run handleScroll once to set the initial visible window.
|
|
1912
|
+
handleScroll();
|
|
1933
1913
|
|
|
1934
1914
|
return () =>
|
|
1935
1915
|
container.removeEventListener("scroll", handleScroll);
|
|
1936
|
-
}, [totalCount, overscan, stickToBottom
|
|
1916
|
+
}, [totalCount, itemHeight, overscan, stickToBottom]);
|
|
1937
1917
|
|
|
1938
1918
|
const scrollToBottom = useCallback(
|
|
1939
1919
|
(behavior: ScrollBehavior = "smooth") => {
|
|
@@ -1949,16 +1929,17 @@ function createProxyHandler<T>(
|
|
|
1949
1929
|
|
|
1950
1930
|
const scrollToIndex = useCallback(
|
|
1951
1931
|
(index: number, behavior: ScrollBehavior = "smooth") => {
|
|
1952
|
-
if (containerRef.current
|
|
1932
|
+
if (containerRef.current) {
|
|
1953
1933
|
containerRef.current.scrollTo({
|
|
1954
|
-
top:
|
|
1934
|
+
top: index * itemHeight,
|
|
1955
1935
|
behavior,
|
|
1956
1936
|
});
|
|
1957
1937
|
}
|
|
1958
1938
|
},
|
|
1959
|
-
[
|
|
1939
|
+
[itemHeight]
|
|
1960
1940
|
);
|
|
1961
1941
|
|
|
1942
|
+
// Same virtualizer props as before
|
|
1962
1943
|
const virtualizerProps = {
|
|
1963
1944
|
outer: {
|
|
1964
1945
|
ref: containerRef,
|
|
@@ -1966,13 +1947,13 @@ function createProxyHandler<T>(
|
|
|
1966
1947
|
},
|
|
1967
1948
|
inner: {
|
|
1968
1949
|
style: {
|
|
1969
|
-
height: `${
|
|
1950
|
+
height: `${totalCount * itemHeight}px`,
|
|
1970
1951
|
position: "relative",
|
|
1971
1952
|
},
|
|
1972
1953
|
},
|
|
1973
1954
|
list: {
|
|
1974
1955
|
style: {
|
|
1975
|
-
transform: `translateY(${
|
|
1956
|
+
transform: `translateY(${range.startIndex * itemHeight}px)`,
|
|
1976
1957
|
},
|
|
1977
1958
|
},
|
|
1978
1959
|
};
|