From 3e06ef64cc5da30f7b2ab209d9d669e6ac8478ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D5=A1=D3=84=D5=A1?= Date: Sun, 1 Sep 2024 09:34:24 +0800 Subject: [PATCH] fix(modal): modal position when keyboard appears (#3691) * feat(theme): add h-[--visual-viewport-height] to modal wrapper * fix(modal): apply --visual-viewport-height * chore(changeset): add changeset --- .changeset/seven-apricots-happen.md | 6 ++++++ .../components/modal/src/modal-content.tsx | 18 ++++++++++++++++-- packages/core/theme/src/components/modal.ts | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 .changeset/seven-apricots-happen.md diff --git a/.changeset/seven-apricots-happen.md b/.changeset/seven-apricots-happen.md new file mode 100644 index 0000000000..feb0d79df8 --- /dev/null +++ b/.changeset/seven-apricots-happen.md @@ -0,0 +1,6 @@ +--- +"@nextui-org/modal": patch +"@nextui-org/theme": patch +--- + +adjust modal position when keyboard appears (#2837) diff --git a/packages/components/modal/src/modal-content.tsx b/packages/components/modal/src/modal-content.tsx index 23fec3da48..f9be88207a 100644 --- a/packages/components/modal/src/modal-content.tsx +++ b/packages/components/modal/src/modal-content.tsx @@ -8,7 +8,7 @@ import {TRANSITION_VARIANTS} from "@nextui-org/framer-utils"; import {CloseIcon} from "@nextui-org/shared-icons"; import {domAnimation, LazyMotion, m} from "framer-motion"; import {useDialog} from "@react-aria/dialog"; -import {chain, mergeProps} from "@react-aria/utils"; +import {chain, mergeProps, useViewportSize} from "@react-aria/utils"; import {HTMLNextUIProps} from "@nextui-org/system"; import {KeyboardEvent} from "react"; @@ -42,6 +42,8 @@ const ModalContent = forwardRef<"div", ModalContentProps, KeysToOmit>((props, _) const Component = as || DialogComponent || "div"; + const viewport = useViewportSize(); + const {dialogProps} = useDialog( { role, @@ -97,8 +99,18 @@ const ModalContent = forwardRef<"div", ModalContentProps, KeysToOmit>((props, _) ); }, [backdrop, disableAnimation, getBackdropProps]); + // set the height dynamically to avoid keyboard covering the bottom modal + const viewportStyle = { + "--visual-viewport-height": viewport.height + "px", + }; + const contents = disableAnimation ? ( -
+
{content}
) : ( @@ -111,6 +123,8 @@ const ModalContent = forwardRef<"div", ModalContentProps, KeysToOmit>((props, _) initial="exit" variants={scaleInOut} {...motionProps} + // @ts-ignore + style={viewportStyle} > {content} diff --git a/packages/core/theme/src/components/modal.ts b/packages/core/theme/src/components/modal.ts index 1fbc9683c5..b47b3dd76b 100644 --- a/packages/core/theme/src/components/modal.ts +++ b/packages/core/theme/src/components/modal.ts @@ -32,6 +32,7 @@ const modal = tv({ "z-50", "overflow-x-auto", "justify-center", + "h-[--visual-viewport-height]", ], base: [ "flex",