From bd171b83ef34a21e2d057b3908b77d3ada47bd61 Mon Sep 17 00:00:00 2001 From: Emil Kowalski <36730035+emilkowalski@users.noreply.github.com> Date: Fri, 13 Sep 2024 22:39:38 +0200 Subject: [PATCH] feat: add prop to disable input repositioning (#410) * Reset body styles * Rename prop --- README.md | 2 +- src/index.tsx | 19 ++++--------------- src/use-scale-background.ts | 13 ++++++++++--- test/src/app/globals.css | 10 +--------- test/src/app/page.tsx | 1 + 5 files changed, 17 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 550a5bc3..f8eb899b 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Additional props: `direction`: Direction of the drawer. Can be `top` or `bottom`, `left`, `right`. Defaults to `bottom`. -`disablePreventScroll`: When `true` scroll prevention mechanism will be disabled. Scroll prevention ensures that page will not scroll on mobile when opening drawer. However this mechanism gets confused when drawer has an input with autofocus and therefore opens simulataneosly with touch keyboard. Defaults to `true`. `modal` set to `false` also disables it. +`repositionInputs`: When `true` Vaul will reposition inputs rather than scroll then into view if the keyboard is in the way. Setting it to `false` will fall back to the default browser behavior. `noBodyStyles`: When `true` the `body` doesn't get any styles assigned from Vaul. diff --git a/src/index.tsx b/src/index.tsx index 8a05d569..68c35dc7 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -51,8 +51,8 @@ export type DialogProps = { nested?: boolean; onClose?: () => void; direction?: 'top' | 'bottom' | 'left' | 'right'; - disablePreventScroll?: boolean; defaultOpen?: boolean; + repositionInputs?: boolean; } & (WithFadeFromProps | WithoutFadeFromProps); export function Root({ @@ -76,7 +76,7 @@ export function Root({ noBodyStyles, direction = 'bottom', defaultOpen = false, - disablePreventScroll = false, + repositionInputs = true, }: DialogProps) { const [isOpen = false, setIsOpen] = useControllableState({ defaultProp: defaultOpen, @@ -126,7 +126,7 @@ export function Root({ }); usePreventScroll({ - isDisabled: !isOpen || isDragging || !modal || justReleased || !hasBeenOpened || disablePreventScroll, + isDisabled: !isOpen || isDragging || !modal || justReleased || !hasBeenOpened || !repositionInputs, }); function getScale() { @@ -401,17 +401,6 @@ export function Root({ }, TRANSITIONS.DURATION * 1000); // seconds to ms } - React.useEffect(() => { - if (!isOpen && shouldScaleBackground) { - // Can't use `onAnimationEnd` as the component will be invisible by then - const id = setTimeout(() => { - reset(document.body); - }, 200); - - return () => clearTimeout(id); - } - }, [isOpen, shouldScaleBackground]); - function resetDrawer() { if (!drawerRef.current) return; const wrapper = document.querySelector('[data-vaul-drawer-wrapper]'); @@ -699,7 +688,7 @@ export const Content = React.forwardRef(function ( const wasBeyondThePointRef = React.useRef(false); const hasSnapPoints = snapPoints && snapPoints.length > 0; useScaleBackground(); - + const isDeltaInDirection = (delta: { x: number; y: number }, direction: DrawerDirection, threshold = 0) => { if (wasBeyondThePointRef.current) return true; diff --git a/src/use-scale-background.ts b/src/use-scale-background.ts index 2c360e38..a578a698 100644 --- a/src/use-scale-background.ts +++ b/src/use-scale-background.ts @@ -1,6 +1,6 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { useDrawerContext } from './context'; -import { assignStyle, chain, isVertical } from './helpers'; +import { assignStyle, chain, isVertical, reset } from './helpers'; import { BORDER_RADIUS, TRANSITIONS, WINDOW_TOP_OFFSET } from './constants'; const noop = () => () => {}; @@ -8,6 +8,7 @@ const noop = () => () => {}; export function useScaleBackground() { const { direction, isOpen, shouldScaleBackground, setBackgroundColorOnScale, noBodyStyles } = useDrawerContext(); const timeoutIdRef = React.useRef(null); + const initialBackgroundColor = useMemo(() => document.body.style.backgroundColor, []); function getScale() { return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth; @@ -44,8 +45,14 @@ export function useScaleBackground() { wrapperStylesCleanup(); timeoutIdRef.current = window.setTimeout(() => { bodyAndWrapperCleanup(); + + if (initialBackgroundColor) { + document.body.style.background = initialBackgroundColor; + } else { + document.body.style.removeProperty('background'); + } }, TRANSITIONS.DURATION * 1000); }; } - }, [isOpen, shouldScaleBackground]); + }, [isOpen, shouldScaleBackground, initialBackgroundColor]); } diff --git a/test/src/app/globals.css b/test/src/app/globals.css index 79aece3a..aa832064 100644 --- a/test/src/app/globals.css +++ b/test/src/app/globals.css @@ -2,17 +2,9 @@ @tailwind components; @tailwind utilities; -html, -body { - overflow: hidden; -} - body, main { - min-height: 100vh; - /* mobile viewport bug fix */ - min-height: -webkit-fill-available; - overflow-x: hidden; + min-height: 500vh; } html { diff --git a/test/src/app/page.tsx b/test/src/app/page.tsx index c49d797b..783264eb 100644 --- a/test/src/app/page.tsx +++ b/test/src/app/page.tsx @@ -13,6 +13,7 @@ export default function Page() { Non-dismissible Initial snap Controlled + Controlled ); }