diff --git a/stories/react/advanced/Collapse nested.stories.tsx b/stories/react/advanced/Collapse nested.stories.tsx
new file mode 100644
index 000000000..d89f122ef
--- /dev/null
+++ b/stories/react/advanced/Collapse nested.stories.tsx
@@ -0,0 +1,101 @@
+import { Meta, StoryObj } from "@storybook/react";
+import { VList, VListHandle } from "../../../src";
+import React, {
+ CSSProperties,
+ ReactNode,
+ useMemo,
+ useRef,
+ useState,
+} from "react";
+import { range } from "../common";
+
+export default {
+ component: VList,
+} as Meta;
+
+const itemStyle: CSSProperties = {
+ borderTop: "solid 1px limegreen",
+ background: "#fff",
+ padding: 32,
+};
+
+type Data = {
+ id: number;
+};
+
+const Item = ({ content }: { content: ReactNode }) => {
+ return
{content}
;
+};
+
+export const Default: StoryObj = {
+ name: "Collapse nested",
+ render: () => {
+ const [itemCollapseState, setItemCollapseState] = useState<
+ Record
+ >({});
+ const id = useRef(0);
+ const createItem = (): Data => {
+ return {
+ id: id.current++,
+ };
+ };
+ const createItems = (num: number) => range(num, createItem);
+
+ const ref = useRef(null);
+ const [items] = useState(() => createItems(30));
+ const elements = useMemo(
+ () =>
+ items.map((d) => (
+ - {
+ setItemCollapseState((state) => ({
+ ...state,
+ [id]: !state[id],
+ }));
+ }}
+ />
+ }
+ />
+ )),
+ [items, itemCollapseState],
+ );
+
+ return (
+
+ {elements}
+
+ );
+ },
+};
+
+const Collapser = ({
+ id,
+ collapseState,
+ toggleCollapse,
+}: {
+ id: number;
+ collapseState: Record;
+ toggleCollapse: (id: string) => void;
+}) => {
+ return new Array(5)
+ .fill(0)
+ .map((v, i) => i)
+ .map((index) => (
+
toggleCollapse(`${id}-${index}`)}
+ >
+ ));
+};