Skip to content

Commit 0e418eb

Browse files
Fix modal spa lock (#1061)
* feat: failing test * fix: failing test * changeset
1 parent ea16f34 commit 0e418eb

File tree

7 files changed

+103
-1
lines changed

7 files changed

+103
-1
lines changed

.changeset/itchy-laws-hunt.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik-ui/headless': patch
3+
---
4+
5+
fix: cleanup scroll locking
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { component$ } from '@builder.io/qwik';
2+
3+
export default component$(() => {
4+
return <div>Test Route</div>;
5+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
export const api = {
2+
modal: [
3+
{
4+
'modal-close': [],
5+
},
6+
{
7+
'modal-content': [],
8+
},
9+
{
10+
'modal-context': [],
11+
},
12+
{
13+
'modal-description': [],
14+
},
15+
{
16+
'modal-footer': [],
17+
},
18+
{
19+
'modal-header': [],
20+
},
21+
{
22+
'modal-panel': [],
23+
},
24+
{
25+
'modal-root': [],
26+
},
27+
{
28+
'modal-title': [],
29+
},
30+
{
31+
'modal-trigger': [],
32+
},
33+
{
34+
'use-modal': [],
35+
},
36+
],
37+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { component$, useStyles$ } from '@builder.io/qwik';
2+
import { Modal, Label } from '@qwik-ui/headless';
3+
4+
export default component$(() => {
5+
useStyles$(styles);
6+
7+
return (
8+
<Modal.Root>
9+
<Modal.Trigger class="modal-trigger">Open Modal</Modal.Trigger>
10+
<Modal.Panel class="modal-panel">
11+
<Modal.Title>Edit Profile</Modal.Title>
12+
<Modal.Description>
13+
You can update your profile here. Hit the save button when finished.
14+
</Modal.Description>
15+
<Label>
16+
Name
17+
<input type="text" placeholder="John Doe" />
18+
</Label>
19+
<Label>
20+
Email
21+
<input type="text" placeholder="[email protected]" />
22+
</Label>
23+
<footer>
24+
<Modal.Close class="modal-close">Cancel</Modal.Close>
25+
<Modal.Close class="modal-close">Save Changes</Modal.Close>
26+
</footer>
27+
<Link href="../../../test-route">SPA NAVIGATION</Link>
28+
</Modal.Panel>
29+
</Modal.Root>
30+
);
31+
});
32+
33+
// internal
34+
import styles from '../snippets/modal.css?inline';
35+
import { Link } from '@builder.io/qwik-city';

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

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import { modalContextId } from './modal-context';
1616

1717
import styles from './modal.css?inline';
1818
import { useModal } from './use-modal';
19+
import { isServer } from '@builder.io/qwik/build';
20+
import { enableBodyScroll } from 'body-scroll-lock-upgrade';
1921

2022
export type ModalProps = Omit<PropsOf<'dialog'>, 'open'> & {
2123
onShow$?: QRL<() => void>;
@@ -59,7 +61,10 @@ export const HModalPanel = component$((props: PropsOf<'dialog'>) => {
5961
}
6062

6163
cleanup(async () => {
64+
if (isServer) return;
6265
await deactivateFocusTrap(focusTrap);
66+
if (!panelRef.value) return;
67+
enableBodyScroll(panelRef.value);
6368
});
6469
});
6570

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

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export const HModalTrigger = component$((props: PropsOf<'button'>) => {
1111
return (
1212
<button
1313
aria-haspopup="dialog"
14-
aria-label="Open Theme Customization Panel"
1514
aria-expanded={context.showSig.value}
1615
data-open={context.showSig.value ? '' : undefined}
1716
data-closed={!context.showSig.value ? '' : undefined}

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

+16
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,22 @@ test.describe('Scroll locking', () => {
137137
}),
138138
).toBe(true);
139139
});
140+
141+
test(`GIVEN a modal
142+
WHEN navigating to another page in SPA
143+
THEN the body should not have overflow hidden`, async ({ page }) => {
144+
const { driver: d } = await setup(page, 'test-spa-scroll');
145+
146+
await expect(page.locator('body')).not.toHaveCSS('overflow', 'hidden');
147+
148+
await d.openModal();
149+
150+
await expect(page.locator('body')).toHaveCSS('overflow', 'hidden');
151+
152+
await page.click('[q\\:link]');
153+
154+
await expect(page.locator('body')).not.toHaveCSS('overflow', 'hidden');
155+
});
140156
});
141157

142158
test.describe('Focus Trap', () => {

0 commit comments

Comments
 (0)