From 4c6a35d3ff53b5f9c6fd386be87f288a03b6abcd Mon Sep 17 00:00:00 2001 From: Alimnfl Date: Thu, 4 Jun 2026 13:25:54 +0700 Subject: [PATCH 1/5] Introduces a `resizable` prop feature. --- components/paper-dialog.tsx | 296 +++++++++++++++++++++++++++++++++--- 1 file changed, 271 insertions(+), 25 deletions(-) diff --git a/components/paper-dialog.tsx b/components/paper-dialog.tsx index fc7e62b90..e1b837d4e 100644 --- a/components/paper-dialog.tsx +++ b/components/paper-dialog.tsx @@ -12,6 +12,7 @@ import { forwardRef, useCallback, useEffect, + useRef, } from "react"; import { ButtonStyles, ButtonVariants } from "./button"; import styled, { css, CSSProp } from "styled-components"; @@ -54,6 +55,16 @@ export interface PaperDialogProps { width?: string; title?: string; subtitle?: string; + resizable?: boolean | PaperDialogResizable; + onResize?: (size: { width?: number; height?: number }) => void; + onResizeComplete?: (size: { width?: number; height?: number }) => void; +} + +export interface PaperDialogResizable { + minWidth?: string; + maxWidth?: string; + minHeight?: string; + maxHeight?: string; } export interface PaperDialogIcons { @@ -110,6 +121,9 @@ const PaperDialog = forwardRef( controls = ["minimize", closable ? "close" : ""], width, height, + resizable: _resizable = false, + onResize, + onResizeComplete, }, ref ) => { @@ -117,13 +131,177 @@ const PaperDialog = forwardRef( const paperDialogTheme = currentTheme.paperDialog; const dragControls = useDragControls(); + const resizable = resolveResizable(_resizable); + const [showTitlebar, setShowTitlebar] = useState(false); const [dialogState, setDialogState] = useState("closed"); + const [resizeWidth, setResizeWidth] = useState(null); + const [resizeHeight, setResizeHeight] = useState(null); + + const isResizingDesktop = useRef(false); + const isResizingMobile = useRef(false); + const resizeStartX = useRef(0); + const resizeStartWidth = useRef(0); + const resizeStartY = useRef(0); + const resizeStartHeight = useRef(0); + + // Track last pointer Y and timestamp for velocity-based minimize on mobile resize + const lastPointerY = useRef(0); + const lastPointerTime = useRef(0); + const velocityRef = useRef(0); + + const dialogRef = useRef(null); + + const isLeft = position === "left"; + + const handleDesktopResizePointerDown = useCallback( + (e: React.PointerEvent) => { + if (!resizable || mobile) return; + e.preventDefault(); + e.stopPropagation(); + isResizingDesktop.current = true; + resizeStartX.current = e.clientX; + resizeStartWidth.current = + dialogRef.current?.getBoundingClientRect().width ?? + resizeWidth ?? + window.innerWidth * 0.92; + + const minPx = parsePx(resizable.minWidth); + const maxPx = parsePx(resizable.maxWidth); + + const onMove = (ev: PointerEvent) => { + if (!isResizingDesktop.current) return; + const delta = isLeft + ? ev.clientX - resizeStartX.current + : resizeStartX.current - ev.clientX; + const next = Math.min( + maxPx, + Math.max(minPx, resizeStartWidth.current + delta) + ); + setResizeWidth(next); + onResize?.({ width: next }); + }; + + const onUp = () => { + isResizingDesktop.current = false; + window.removeEventListener("pointermove", onMove); + window.removeEventListener("pointerup", onUp); + const finalWidth = resizeWidth ?? resizeStartWidth.current; + onResizeComplete?.({ width: finalWidth }); + }; + + window.addEventListener("pointermove", onMove); + window.addEventListener("pointerup", onUp); + }, + [ + resizable, + mobile, + isLeft, + resizable, + resizeWidth, + setResizeWidth, + onResize, + onResizeComplete, + ] + ); + + const handleMobileResizePointerDown = useCallback( + (e: React.PointerEvent) => { + if (!resizable || !mobile) return; + e.preventDefault(); + e.stopPropagation(); + isResizingMobile.current = true; + resizeStartY.current = e.clientY; + resizeStartHeight.current = + dialogRef.current?.getBoundingClientRect().height ?? + resizeHeight ?? + window.innerHeight * 0.88; + + lastPointerY.current = e.clientY; + lastPointerTime.current = performance.now(); + + const maxPx = parsePx(resizable.maxHeight); + const minPx = parsePx(resizable.minHeight); + + const onMove = (ev: PointerEvent) => { + if (!isResizingMobile.current) return; + const delta = resizeStartY.current - ev.clientY; + const DAMPING = 0.72; + + const next = Math.min( + maxPx, + Math.max(minPx, resizeStartHeight.current + delta * DAMPING) + ); + + setResizeHeight(next); + onResize?.({ height: next }); + + const now = performance.now(); + + const dy = ev.clientY - lastPointerY.current; + const dt = now - lastPointerTime.current; + + if (dt > 0) { + velocityRef.current = dy / dt; + } + + lastPointerY.current = ev.clientY; + lastPointerTime.current = performance.now(); + }; + + const onUp = (ev: PointerEvent) => { + isResizingMobile.current = false; + window.removeEventListener("pointermove", onMove); + window.removeEventListener("pointerup", onUp); + + // Compute instantaneous velocity (px/ms, positive = downward) + const dt = performance.now() - lastPointerTime.current; + const velocity = + dt > 0 ? (ev.clientY - lastPointerY.current) / dt : 0; + + if (velocityRef.current > 0.5) { + setDialogState("minimized"); + setShowTitlebar(true); + setTimeout(() => { + setResizeHeight(null); + }, 300); + } else { + const finalHeight = + dialogRef.current?.getBoundingClientRect().height ?? + resizeHeight ?? + resizeStartHeight.current; + onResizeComplete?.({ height: finalHeight }); + } + }; + + window.addEventListener("pointermove", onMove); + window.addEventListener("pointerup", onUp); + }, + [ + resizable, + mobile, + resizable, + resizeHeight, + setResizeHeight, + onResize, + onResizeComplete, + lastPointerTime, + lastPointerY, + velocityRef, + ] + ); + + const resolvedWidth = resizeWidth != null ? `${resizeWidth}px` : width; + const resolvedHeight = resizeHeight != null ? `${resizeHeight}px` : height; + const closeDialog = useCallback( async (withTimeout: boolean = true) => { const close = async () => await setDialogState("closed"); + await setResizeHeight(null); + await setResizeWidth(null); + if (mobile) { await setDialogState("minimized"); @@ -153,8 +331,6 @@ const PaperDialog = forwardRef( }, })); - const isLeft = position === "left"; - const handleEscape = useCallback( (e: KeyboardEvent) => { if ( @@ -194,9 +370,7 @@ const PaperDialog = forwardRef( await close(); } }} - styles={{ - self: styles?.overlayStyle, - }} + styles={{ self: styles?.overlayStyle }} show={dialogState === "restored"} /> )} @@ -250,10 +424,11 @@ const PaperDialog = forwardRef( )} ( dragDirectionLock dragControls={dragControls} dragConstraints={{ top: 0, bottom: 0 }} - dragElastic={{ - top: 0, - bottom: 0.6, - }} + dragElastic={{ top: 0, bottom: 0.6 }} onDragEnd={(_, info) => { if (info.offset.y > 120 || info.velocity.y > 500) { setDialogState("minimized"); setShowTitlebar(true); } }} - whileDrag={{ - cursor: "grabbing", - userSelect: "none", - }} + whileDrag={{ cursor: "grabbing", userSelect: "none" }} > + {resizable && !mobile && ( + + )} + {closable && controls?.includes("close") && ( ( )} ( size="lg" /> )} - {mobile && closable && ( + + {mobile && ( dragControls.start(e)} + $resizable={!!resizable} + onPointerDown={(e) => { + if (resizable) { + handleMobileResizePointerDown(e); + } else if (closable) { + dragControls.start(e); + } + }} > - + )} + {children} @@ -397,6 +586,34 @@ const PaperDialog = forwardRef( } ); +/** + * Convert a CSS size string to pixels at the current viewport. + * Handles: px | dvw | vw | dvh | vh — falls back to parseInt for bare numbers. + */ +function parsePx(value: string): number { + const n = parseFloat(value); + if (value.endsWith("dvw") || value.endsWith("vw")) + return (n / 100) * window.innerWidth; + if (value.endsWith("dvh") || value.endsWith("vh")) + return (n / 100) * window.innerHeight; + return n; +} + +/** Resolve the `resizable` prop into a normalised config (or null when disabled). */ +function resolveResizable( + resizable: boolean | PaperDialogResizable | undefined +): Required | null { + if (!resizable) return null; + const defaults: Required = { + minWidth: "20dvw", + maxWidth: "90dvw", + minHeight: "20dvh", + maxHeight: "90dvh", + }; + if (resizable === true) return defaults; + return { ...defaults, ...resizable }; +} + const DialogOverlay = styled.div<{ $dialogState: PaperDialogState; $style?: CSSProp; @@ -481,6 +698,32 @@ const MotionDialog = styled(motion.div)<{ ${({ $style }) => $style}; `; +const DesktopResizeHandle = styled.div<{ $isLeft: boolean }>` + position: absolute; + top: 0; + bottom: 0; + width: 6px; + z-index: 10000; + cursor: col-resize; + transition: background-color 0.15s ease; + + ${({ $isLeft }) => + $isLeft + ? css` + right: 0; + border-right: 2px solid transparent; + ` + : css` + left: 0; + border-left: 2px solid transparent; + `} + + &:hover, + &:active { + background-color: rgba(128, 128, 128, 0.18); + } +`; + const ActionButtonWrapper = styled.div<{ $isLeft: boolean; $top: number; @@ -599,7 +842,7 @@ const PaperDialogContent = styled.div<{ ${({ $style }) => $style} `; -const DragIndicatorWrapper = styled(motion.div)` +const DragIndicatorWrapper = styled(motion.div)<{ $resizable?: boolean }>` &, *, *::before, @@ -607,8 +850,6 @@ const DragIndicatorWrapper = styled(motion.div)` box-sizing: border-box; } - box-sizing: border-box; - display: flex; position: absolute; top: -4px; @@ -616,16 +857,18 @@ const DragIndicatorWrapper = styled(motion.div)` transform: translateX(-50%); justify-content: center; width: 100dvw; - cursor: grab; + + cursor: ${({ $resizable }) => ($resizable ? "ns-resize" : "grab")}; height: 40px; &:active { - cursor: grabbing; + cursor: ${({ $resizable }) => ($resizable ? "ns-resize" : "grabbing")}; } `; const DragIndicator = styled(motion.div)<{ $theme?: PaperDialogThemeConfig; + $resizable?: boolean; }>` display: flex; transform: translateY(22px); @@ -633,7 +876,10 @@ const DragIndicator = styled(motion.div)<{ height: 5px; border-radius: 999px; background-color: ${({ $theme }) => $theme?.textColor}; - opacity: 0.3; + opacity: ${({ $resizable }) => ($resizable ? 0.5 : 0.3)}; + transition: + opacity 0.2s ease, + width 0.2s ease; `; const MiniTitleBar = styled(motion.div)<{ From 0b19d499e551368bde77779bc4df20d98d1cee92 Mon Sep 17 00:00:00 2001 From: Alimnfl Date: Thu, 4 Jun 2026 13:43:07 +0700 Subject: [PATCH 2/5] Add stories `resizeable` for the `mobile` mode on `PaperDialog`. --- components/paper-dialog.stories.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/paper-dialog.stories.tsx b/components/paper-dialog.stories.tsx index 4cd694e7b..77a7311b2 100644 --- a/components/paper-dialog.stories.tsx +++ b/components/paper-dialog.stories.tsx @@ -207,7 +207,7 @@ export const Default: Story = { Date: Thu, 4 Jun 2026 15:08:25 +0700 Subject: [PATCH 3/5] Ensures all the test works correctly in PaperDialog (width, height, function). --- components/paper-dialog.tsx | 1 + test/component/paper-dialog.cy.tsx | 407 ++++++++++++++++++++++++++++- 2 files changed, 403 insertions(+), 5 deletions(-) diff --git a/components/paper-dialog.tsx b/components/paper-dialog.tsx index ec519eaa1..a82af81ab 100644 --- a/components/paper-dialog.tsx +++ b/components/paper-dialog.tsx @@ -574,6 +574,7 @@ const PaperDialog = forwardRef( /> )} + { }); }); + context("resizable", () => { + context("object", () => { + context("minWidth", () => { + it("does not resize below the minimum width", () => { + cy.viewport(500, 700); + + cy.mount( + + ); + + cy.findAllByRole("button").eq(0).click(); + cy.wait(500); + + cy.findByLabelText("paper-dialog-resize-handle") + .realMouseDown({ position: "center" }) + .realMouseMove(150, 0) + .realMouseUp(); + + cy.findByLabelText("paper-dialog-wrapper") + .invoke("width") + .should("be.closeTo", 200, 5); + }); + }); + + context("maxWidth", () => { + it("does not resize above the maximum width", () => { + cy.viewport(500, 700); + + cy.mount( + + ); + + cy.findAllByRole("button").eq(0).click(); + cy.wait(500); + + cy.findByLabelText("paper-dialog-resize-handle") + .realMouseDown({ position: "center" }) + .realMouseMove(-150, 0) + .realMouseUp(); + + cy.findByLabelText("paper-dialog-wrapper") + .invoke("width") + .should("be.closeTo", 300, 5); + }); + }); + }); + + context("when resizing wider", () => { + it("renders a wider dialog", () => { + cy.viewport(500, 700); + + cy.mount(); + + cy.findAllByRole("button").eq(0).should("exist").click(); + + cy.wait(500); + + let initialWidth: number; + + cy.findByLabelText("paper-dialog-wrapper") + .invoke("width") + .then((w) => { + initialWidth = w as number; + }); + + cy.findByLabelText("paper-dialog-resize-handle") + .realMouseDown({ position: "center" }) + .realMouseMove(-150, 0) + .realMouseUp(); + + cy.findByLabelText("paper-dialog-wrapper") + .invoke("width") + .then((w) => { + expect(w).to.be.closeTo(initialWidth + 150, 5); + }); + }); + }); + + context("when resizing narrower", () => { + it("renders a narrower dialog", () => { + cy.viewport(500, 700); + + cy.mount(); + + cy.findAllByRole("button").eq(0).should("exist").click(); + + cy.wait(500); + + let initialWidth: number; + + cy.findByLabelText("paper-dialog-wrapper") + .invoke("width") + .then((w) => { + initialWidth = w as number; + }); + + cy.findByLabelText("paper-dialog-resize-handle") + .realMouseDown({ position: "center" }) + .realMouseMove(150, 0) + .realMouseUp(); + + cy.findByLabelText("paper-dialog-wrapper") + .invoke("width") + .then((w) => { + expect(w).to.be.closeTo(initialWidth - 150, 5); + }); + }); + }); + + context("onResize", () => { + it("should shows the width", () => { + cy.viewport(500, 700); + + const onResize = cy.spy().as("onResize"); + + cy.mount(); + + cy.findAllByRole("button").eq(0).should("exist").click(); + + cy.wait(500); + cy.get("@onResize").should("not.have.been.called"); + + cy.findByLabelText("paper-dialog-wrapper").should("be.visible"); + + cy.findByLabelText("paper-dialog-resize-handle") + .realMouseDown({ position: "center" }) + .realMouseMove(-50, 0) + .wait(200) + .realMouseMove(-100, 0) + .wait(200) + .realMouseMove(-150, 0) + .realMouseUp(); + + cy.wait(300); + + cy.get("@onResize") + .its("lastCall.args.0.width") + .should("be.a", "number"); + }); + }); + + context("onResizeComplete", () => { + it("should call onResizeComplete with final width", () => { + cy.viewport(500, 700); + + const onResizeComplete = cy.spy().as("onResizeComplete"); + + cy.mount( + + ); + + cy.findAllByRole("button").eq(0).click(); + + cy.wait(500); + + cy.get("@onResizeComplete").should("not.have.been.called"); + + cy.findByLabelText("paper-dialog-resize-handle") + .realMouseDown({ position: "center" }) + .realMouseMove(-50, 0) + .wait(200) + .realMouseMove(-100, 0) + .wait(200) + .realMouseMove(-150, 0) + .realMouseUp(); + + cy.wait(300); + + cy.get("@onResizeComplete") + .should("have.been.calledOnce") + .its("lastCall.args.0.width") + .should("be.a", "number"); + }); + }); + }); + context("mobile", () => { it("renders with radius 0.75rem, width 100dvw and height 72dvh", () => { cy.viewport(500, 700); @@ -116,6 +302,215 @@ describe("PaperDialog", () => { .and("have.css", "height", "616px"); }); + context("resizable", () => { + context("object", () => { + context("minHeight", () => { + it("does not resize below the minimum height", () => { + cy.viewport(500, 700); + + cy.mount( + + ); + + cy.findAllByRole("button").eq(0).click(); + cy.wait(500); + + cy.findByLabelText("paper-dialog-drag-indicator") + .realMouseDown({ position: "center" }) + .realMouseMove(0, 50) + .wait(200) + .realMouseMove(0, 100) + .wait(200) + .realMouseMove(0, 150) + .wait(200) + .realMouseMove(0, 250) + .realMouseUp(); + + cy.findByLabelText("paper-dialog-wrapper") + .invoke("height") + .should("be.closeTo", 200, 10); + }); + }); + + context("maxHeight", () => { + it("does not resize above the maximum height", () => { + cy.viewport(500, 700); + + cy.mount( + + ); + + cy.findAllByRole("button").eq(0).click(); + cy.wait(500); + + cy.findByLabelText("paper-dialog-drag-indicator") + .realMouseDown({ position: "center" }) + .realMouseMove(0, -50) + .wait(200) + .realMouseMove(0, -100) + .wait(200) + .realMouseMove(0, -150) + .wait(200) + .realMouseMove(0, -250) + .realMouseUp(); + + cy.findByLabelText("paper-dialog-wrapper") + .invoke("height") + .should("be.closeTo", 400, 10); + }); + }); + }); + + context("onResize", () => { + it("should shows the height ", () => { + cy.viewport(500, 700); + + const onResize = cy.spy().as("onResize"); + + cy.mount( + + ); + + cy.findAllByRole("button").eq(0).should("exist").click(); + + cy.wait(500); + cy.get("@onResize").should("not.have.been.called"); + + cy.findByLabelText("paper-dialog-wrapper").should("be.visible"); + + cy.findByLabelText("paper-dialog-drag-indicator") + .realMouseDown({ position: "center" }) + .realMouseMove(0, 30) + .wait(200) + .realMouseMove(0, 60) + .wait(200) + .realMouseMove(0, 100) + .realMouseUp(); + + cy.wait(300); + + cy.get("@onResize") + .its("lastCall.args.0.height") + .should("be.a", "number"); + }); + }); + + context("onResizeComplete", () => { + it("should call onResizeComplete with final height", () => { + cy.viewport(500, 700); + + const onResizeComplete = cy.spy().as("onResizeComplete"); + + cy.mount( + + ); + + cy.findAllByRole("button").eq(0).click(); + + cy.wait(500); + + cy.get("@onResizeComplete").should("not.have.been.called"); + + cy.findByLabelText("paper-dialog-drag-indicator") + .realMouseDown({ position: "center" }) + .realMouseMove(0, 30) + .wait(200) + .realMouseMove(0, 60) + .wait(200) + .realMouseMove(0, 100) + .realMouseUp(); + + cy.wait(300); + + cy.get("@onResizeComplete") + .should("have.been.calledOnce") + .its("lastCall.args.0.height") + .should("be.a", "number"); + }); + }); + + context("when dragged fast", () => { + it("should minimize the dialog", () => { + cy.viewport(500, 700); + cy.mount(); + + cy.findAllByRole("button").eq(0).should("exist").click(); + + cy.wait(500); + + cy.findByLabelText("paper-dialog-wrapper").should("be.visible"); + + cy.findByLabelText("paper-dialog-drag-indicator") + .realMouseDown({ position: "center" }) + .realMouseMove(0, 300) + .realMouseUp(); + + cy.wait(300); + cy.findByLabelText("paper-dialog-wrapper").should("not.be.visible"); + }); + }); + + context("when dragged slowly", () => { + it("should not minimize and resize the dialog", () => { + cy.viewport(500, 700); + cy.mount(); + + cy.findAllByRole("button").eq(0).should("exist").click(); + cy.wait(300); + let initialHeight: number; + + cy.findByLabelText("paper-dialog-wrapper") + .should("be.visible") + .then(($el) => { + initialHeight = $el.height()!; + }); + + cy.findByLabelText("paper-dialog-drag-indicator") + .realMouseDown({ position: "center" }) + .realMouseMove(0, 30) + .wait(200) + .realMouseMove(0, 60) + .wait(200) + .realMouseMove(0, 100) + .realMouseUp(); + + cy.wait(300); + + cy.findByLabelText("paper-dialog-wrapper") + .should("be.visible") + .then(($el) => { + const resizedHeight = $el.height()!; + + expect(resizedHeight).to.be.lessThan(initialHeight); + }); + }); + }); + }); + context("user selection", () => { it("renders action buttons without text selection", () => { cy.viewport(500, 700); @@ -165,7 +560,8 @@ describe("PaperDialog", () => { context("drag behavior", () => { context("when dragging icon drag indicator", () => { it("should close the dialog", () => { - cy.viewport(500, 500); + cy.viewport(500, 700); + cy.mount(); cy.findAllByRole("button").eq(0).should("exist").click(); @@ -185,16 +581,17 @@ describe("PaperDialog", () => { context("when dragging in area empty icon drag indicator", () => { it("should close the dialog", () => { - cy.viewport(500, 500); + cy.viewport(500, 700); + cy.mount(); cy.findAllByRole("button").eq(0).should("exist").click(); cy.wait(500); - cy.findByLabelText("paper-dialog-content") + cy.findByLabelText("paper-dialog-drag-indicator") .should("exist") - .realMouseDown({ position: "topRight" }) + .realMouseDown({ position: "right" }) .realMouseMove(0, 350) .realMouseUp(); @@ -306,7 +703,7 @@ describe("PaperDialog", () => { cy.wait(300); cy.findByLabelText("paper-dialog-close-icon").should("not.exist"); - cy.findByLabelText("paper-dialog-drag-indicator").should("not.exist"); + cy.findByLabelText("paper-dialog-drag-indicator").should("exist"); }); context("when clicking overlay-background", () => { From a5056b27de99d92b391eb529b230d8c9af886028 Mon Sep 17 00:00:00 2001 From: Alimnfl Date: Thu, 4 Jun 2026 15:11:58 +0700 Subject: [PATCH 4/5] Add better documentation for `PaperDialog`. --- components/paper-dialog.stories.tsx | 48 +++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/components/paper-dialog.stories.tsx b/components/paper-dialog.stories.tsx index f4520429d..e7dcbd1ee 100644 --- a/components/paper-dialog.stories.tsx +++ b/components/paper-dialog.stories.tsx @@ -63,6 +63,54 @@ You can override the default control icons (e.g. close and restore) by passing c /> \`\`\` + + +### 📏 Resizable + +PaperDialog can be resized on both desktop and mobile devices. + +Desktop: +- Drag the resize handle on the dialog edge to adjust the width. + +Mobile: +- Drag the top indicator to adjust the height. + +You can enable resizing with a boolean value: + +\`\`\`tsx + +\`\`\` + + +Or configure resize constraints: + +\`\`\`tsx + +\`\`\` + +### 📐 Resize Callbacks + +Use \`onResize\` to react to size changes while dragging and \`onResizeComplete\` to react when resizing has finished: + +\`\`\`tsx + { + console.log(width, height); + }} + onResizeComplete={({ width, height }) => { + console.log("Final size:", width, height); + }} +/> +\`\`\` + ### 📝 Notes - Use \`styles\` prop to override default styles. - Use the \`icons\` prop to override default icons. From 60cf9929d7ad553549bc4f936e310cff0a96092a Mon Sep 17 00:00:00 2001 From: Alimnfl Date: Thu, 4 Jun 2026 15:22:59 +0700 Subject: [PATCH 5/5] Add `resizeable` on the `nested` story. --- components/paper-dialog.stories.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/paper-dialog.stories.tsx b/components/paper-dialog.stories.tsx index e7dcbd1ee..ff5e96c3e 100644 --- a/components/paper-dialog.stories.tsx +++ b/components/paper-dialog.stories.tsx @@ -988,6 +988,7 @@ export const Nested: Story = { overflow: auto; `, }} + resizable closable width="90vw" > @@ -1041,6 +1042,7 @@ export const Nested: Story = {