Skip to content

Commit 69da55a

Browse files
Merge pull request #560 from thejackshelton/fix-modal
fix(modal): modal on iOS maintains proper scroll position & proper escape scroll unlock when tabbing
2 parents fff68b4 + 9b673af commit 69da55a

File tree

5 files changed

+22
-29
lines changed

5 files changed

+22
-29
lines changed

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
"@storybook/test-runner": "0.13.0",
6262
"@storybook/testing-library": "0.2.2",
6363
"@testing-library/cypress": "9.0.0",
64-
"@types/body-scroll-lock": "3.1.1",
6564
"@types/eslint": "^8.44.2",
6665
"@types/estree-jsx": "^1.0.3",
6766
"@types/node": "^20.5.7",
@@ -72,7 +71,6 @@
7271
"all-contributors-cli": "^6.26.1",
7372
"autoprefixer": "^10.4.15",
7473
"axe-core": "^4.7.2",
75-
"body-scroll-lock": "4.0.0-beta.0",
7674
"chromatic": "^6.24.1",
7775
"clipboard-copy": "4.0.1",
7876
"commitizen": "^4.3.0",

packages/kit-headless/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"dependencies": {
2828
"@qwik-ui/utils": "workspace:*",
2929
"@floating-ui/dom": "^1.0.10",
30-
"body-scroll-lock": "^4.0.0-beta.0",
30+
"body-scroll-lock-upgrade": "1.1.0",
3131
"country-list-json": "^1.1.0",
3232
"focus-trap": "^7.5.3",
3333
"libphonenumber-js": "^1.10.43"

packages/kit-headless/src/components/modal/modal-behavior.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { QwikMouseEvent } from '@builder.io/qwik';
21
import { FocusTrap, createFocusTrap } from 'focus-trap';
32

43
export type WidthState = {
54
width: number | null;
65
};
76

8-
import { clearAllBodyScrollLocks } from 'body-scroll-lock';
7+
import { clearAllBodyScrollLocks } from 'body-scroll-lock-upgrade';
98

109
/**
1110
* Traps the focus of the given Modal
@@ -54,7 +53,7 @@ export async function closeModal(modal: HTMLDialogElement) {
5453
*/
5554
export function wasModalBackdropClicked(
5655
modal: HTMLDialogElement | undefined,
57-
clickEvent: QwikMouseEvent,
56+
clickEvent: MouseEvent,
5857
): boolean {
5958
if (!modal) {
6059
return false;

packages/kit-headless/src/components/modal/modal.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {
22
$,
33
QRL,
44
QwikIntrinsicElements,
5-
QwikMouseEvent,
65
Signal,
76
Slot,
87
component$,
@@ -21,7 +20,7 @@ import {
2120
wasModalBackdropClicked,
2221
} from './modal-behavior';
2322

24-
import { disableBodyScroll } from 'body-scroll-lock';
23+
import { disableBodyScroll } from 'body-scroll-lock-upgrade';
2524

2625
import styles from './modal.css?inline';
2726

@@ -47,15 +46,20 @@ export const Modal = component$((props: ModalProps) => {
4746

4847
const focusTrap = trapFocus(modal);
4948

50-
window.addEventListener(
51-
'keydown',
52-
overrideNativeDialogEscapeBehaviorWith(() => (showSig.value = false)),
53-
{ once: true },
54-
);
49+
const escapeKeyListener = overrideNativeDialogEscapeBehaviorWith(() => {
50+
showSig.value = false;
51+
});
52+
53+
window.addEventListener('keydown', escapeKeyListener);
5554

5655
if (isOpen) {
56+
// HACK: keep modal scroll position in place with iOS
57+
const storedRequestAnimationFrame = window.requestAnimationFrame;
58+
window.requestAnimationFrame = () => 42;
59+
5760
showModal(modal);
5861
disableBodyScroll(modal, { reserveScrollBarGap: true });
62+
window.requestAnimationFrame = storedRequestAnimationFrame;
5963
props.onShow$?.();
6064
activateFocusTrap(focusTrap);
6165
} else {
@@ -65,10 +69,11 @@ export const Modal = component$((props: ModalProps) => {
6569

6670
cleanup(() => {
6771
deactivateFocusTrap(focusTrap);
72+
window.removeEventListener('keydown', escapeKeyListener);
6873
});
6974
});
7075

71-
const closeOnBackdropClick$ = $((event: QwikMouseEvent) => {
76+
const closeOnBackdropClick$ = $((event: MouseEvent) => {
7277
if (props.alert === true || props.closeOnBackdropClick === false) {
7378
return;
7479
}

pnpm-lock.yaml

Lines changed: 6 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)