diff --git a/lib/Dialog/Dialog.tsx b/lib/Dialog/Dialog.tsx index 519b1e7..8b9b89b 100644 --- a/lib/Dialog/Dialog.tsx +++ b/lib/Dialog/Dialog.tsx @@ -1,6 +1,7 @@ import * as React from "react"; import Portal from "../Portal"; import { + FocusTrap, SystemError, SystemKeys, resolvePropWithRenderContext, @@ -8,6 +9,7 @@ import { import type { MergeElementProps, PropWithRenderContext } from "../types"; import { componentWithForwardedRef, + getScrollingState, useDeterministicId, useEventListener, useIsMounted, @@ -97,7 +99,9 @@ const DialogBase = (props: Props, ref: React.Ref) => { previouslyFocusedElement.current = document.activeElement as HTMLElement | null; - disablePageScroll(); + const isBodyScrolling = getScrollingState(document.body).vertical; + + if (isBodyScrolling) disablePageScroll(); } else { enablePageScroll(); @@ -127,9 +131,11 @@ const DialogBase = (props: Props, ref: React.Ref) => { target: document, eventType: "keydown", handler: event => { - event.preventDefault(); + if (event.key === SystemKeys.ESCAPE) { + event.preventDefault(); - if (event.key === SystemKeys.ESCAPE) emitClose(); + emitClose(); + } }, }, open, @@ -140,26 +146,28 @@ const DialogBase = (props: Props, ref: React.Ref) => { return ( -
+ -
+
); }; diff --git a/lib/Dialog/components/Content.tsx b/lib/Dialog/components/Content.tsx index 3e302be..855c113 100644 --- a/lib/Dialog/components/Content.tsx +++ b/lib/Dialog/components/Content.tsx @@ -1,6 +1,5 @@ import * as React from "react"; import { logger } from "../../internals"; -import FocusTrap from "../../internals/FocusTrap"; import type { MergeElementProps } from "../../types"; import { componentWithForwardedRef, useDeterministicId } from "../../utils"; import { DialogContext } from "../context"; @@ -39,19 +38,17 @@ const ContentBase = (props: Props, ref: React.Ref) => { } return ( - -
- {children} -
-
+
+ {children} +
); }; diff --git a/lib/Menu/BaseMenu.tsx b/lib/Menu/BaseMenu.tsx index 4cc0537..75cc6c7 100644 --- a/lib/Menu/BaseMenu.tsx +++ b/lib/Menu/BaseMenu.tsx @@ -60,7 +60,7 @@ const BaseMenuBase = (props: Props, ref: React.Ref) => { ); - if (trapFocus) + if (trapFocus) { return ( ) => { {renderMenu()} ); + } return renderMenu(); }; diff --git a/lib/utils/get-scrolling-state.ts b/lib/utils/get-scrolling-state.ts new file mode 100644 index 0000000..a924f1b --- /dev/null +++ b/lib/utils/get-scrolling-state.ts @@ -0,0 +1,31 @@ +const getScrollingState = (element: HTMLElement) => { + const isScrollable = (node: HTMLElement) => { + const overflow = getComputedStyle(node).getPropertyValue("overflow"); + + return overflow.includes("auto") || overflow.includes("scroll"); + }; + + const getScrollParent = (element: HTMLElement) => { + let current = element.parentNode as HTMLElement | null; + + while (current) { + if (!(element instanceof HTMLElement)) break; + if (!(element instanceof SVGElement)) break; + + if (isScrollable(current)) return current; + + current = current.parentNode as HTMLElement | null; + } + + return document.scrollingElement || document.documentElement; + }; + + const scrollParent = getScrollParent(element); + + return { + vertical: scrollParent.scrollHeight > scrollParent.clientHeight, + horizontal: scrollParent.scrollWidth > scrollParent.clientWidth, + }; +}; + +export default getScrollingState; diff --git a/lib/utils/index.ts b/lib/utils/index.ts index 77fb5cf..8868b72 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -17,6 +17,7 @@ export { default as createVirtualElement } from "./create-virtual-element"; export { default as dispatchDiscreteCustomEvent } from "./dispatch-discrete-custom-event"; export * from "./dom"; export { default as forkRefs } from "./fork-refs"; +export { default as getScrollingState } from "./get-scrolling-state"; export * from "./is"; export * from "./math"; export { default as requestFormSubmit } from "./request-form-submit"; diff --git a/package.json b/package.json index 9798923..e281f33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@styleless-ui/react", - "version": "1.0.0-rc.1", + "version": "1.0.0-rc.2", "description": "Completely unstyled, headless and accessible React UI components.", "author": "mimshins ", "license": "MIT",