Skip to content

Commit cc6516a

Browse files
committed
refactor(modal): restructure helpers adding animation support
1 parent f6ce318 commit cc6516a

File tree

2 files changed

+32
-32
lines changed

2 files changed

+32
-32
lines changed

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

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { QRL, QwikMouseEvent } from '@builder.io/qwik';
22
import { FocusTrap, createFocusTrap } from 'focus-trap';
33

4+
export type WidthState = {
5+
width: number | null;
6+
};
7+
48
/**
59
* Traps the focus of the given Modal
610
* @returns FocusTrap
@@ -29,23 +33,22 @@ export function deactivateFocusTrap(focusTrap: FocusTrap | null) {
2933

3034
/**
3135
* Shows the given Modal.
32-
* Applies CSS-Class to animate the modal-showing.
36+
* Applies a CSS-Class to animate the modal-showing.
3337
* Calls the given callback that is executed after the Modal has been opened.
3438
*/
3539
export async function showModal(modal: HTMLDialogElement, onShow$?: QRL<() => void>) {
3640
modal.showModal();
37-
opening(modal);
41+
supportShowAnimation(modal);
3842
await onShow$?.();
3943
}
4044

4145
/**
4246
* Closes the given Modal.
43-
* Applies CSS-Class to animate the Modal-closing.
47+
* Applies a CSS-Class to animate the Modal-closing.
4448
* Calls the given callback that is executed after the Modal has been closed.
4549
*/
4650
export async function closeModal(modal: HTMLDialogElement, onClose$?: QRL<() => void>) {
47-
modal.close();
48-
modal.classList.remove('modal-showing');
51+
supportClosingAnimation(modal, () => modal.close());
4952
await onClose$?.();
5053
}
5154

@@ -78,10 +81,6 @@ export function lockScroll() {
7881
window.document.body.style.overflow = 'hidden';
7982
}
8083

81-
export type WidthState = {
82-
width: number | null;
83-
};
84-
8584
/**
8685
* Unlocks scrolling of the document.
8786
* Adjusts padding of the given scrollbar.
@@ -96,10 +95,12 @@ export function unlockScroll(scrollbar: WidthState) {
9695
}
9796

9897
/**
98+
* When the Modal is opened we are disabling scrolling.
99+
* This means the scrollbar will vanish.
100+
* The scrollbar has a width and causes the Modal to reposition.
99101
*
100-
* Adjusts scrollbar padding
101-
* TODO: Why???
102-
*
102+
* That's why we take the scrollbar-width into account so that the
103+
* Modal does not jump to the right.
103104
*/
104105
export function adjustScrollbar(scrollbar: WidthState, modal: HTMLDialogElement) {
105106
if (scrollbar.width === null) {
@@ -121,7 +122,7 @@ export function overrideNativeDialogEscapeBehaviorWith(continuation: () => void)
121122
}
122123

123124
/**
124-
* When the Modal is closed we are enabling scrolling again.
125+
* When the Modal is closed we are enabling scrolling.
125126
* This means the scrollbar will reappear in the browser.
126127
* The scrollbar has a width and causes the Modal to reposition.
127128
*
@@ -141,27 +142,34 @@ export function keepModalInPlaceWhileScrollbarReappears(
141142
}
142143
}
143144

145+
/*
146+
* Adds CSS-Class to support modal-opening-animation
147+
*/
148+
export function supportShowAnimation(modal: HTMLDialogElement) {
149+
modal.classList.add('modal-showing');
150+
}
151+
144152
/*
145153
* Listens for animation/transition events in order to
146154
* remove Animation-CSS-Classes after animation/transition ended.
147155
*/
148-
export function closing(modal: HTMLDialogElement, onClose$?: QRL<() => void>) {
149-
if (!modal) {
150-
return;
151-
}
152-
156+
export function supportClosingAnimation(
157+
modal: HTMLDialogElement,
158+
afterAnimate: () => void,
159+
) {
160+
modal.classList.remove('modal-showing');
153161
modal.classList.add('modal-closing');
154162

155163
const { animationDuration, transitionDuration } = getComputedStyle(modal);
156164

157165
const runAnimationEnd = () => {
158166
modal.classList.remove('modal-closing');
159-
closeModal(modal, onClose$);
167+
afterAnimate();
160168
};
161169

162170
const runTransitionEnd = () => {
163171
modal.classList.remove('modal-closing');
164-
closeModal(modal, onClose$);
172+
afterAnimate();
165173
};
166174

167175
if (animationDuration !== '0s') {
@@ -170,15 +178,6 @@ export function closing(modal: HTMLDialogElement, onClose$?: QRL<() => void>) {
170178
modal.addEventListener('transitionend', runTransitionEnd, { once: true });
171179
} else {
172180
modal.classList.remove('modal-closing');
173-
closeModal(modal, onClose$);
181+
afterAnimate();
174182
}
175183
}
176-
177-
/*
178-
* Adds CSS-Class to support modal-opening-animation
179-
*/
180-
export function opening(modal: HTMLDialogElement) {
181-
if (!modal) return;
182-
183-
modal.classList.add('modal-showing');
184-
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
WidthState,
1515
activateFocusTrap,
1616
adjustScrollbar,
17-
closing,
17+
closeModal,
1818
deactivateFocusTrap,
1919
keepModalInPlaceWhileScrollbarReappears,
2020
lockScroll,
@@ -63,7 +63,8 @@ export const Modal = component$((props: ModalProps) => {
6363
lockScroll();
6464
} else {
6565
unlockScroll(scrollbar);
66-
closing(modal, props.onClose$);
66+
closeModal(modal);
67+
// animateClosing(modal, props.onClose$);
6768
}
6869

6970
cleanup(() => {

0 commit comments

Comments
 (0)