Skip to content

Commit 00274c4

Browse files
Gregor WoiwodeGregor Woiwode
Gregor Woiwode
authored and
Gregor Woiwode
committed
refactor(dialog): add rename files
1 parent 9165230 commit 00274c4

File tree

8 files changed

+129
-127
lines changed

8 files changed

+129
-127
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import {
2+
$,
3+
QwikIntrinsicElements,
4+
QwikMouseEvent,
5+
Signal,
6+
Slot,
7+
component$,
8+
useSignal,
9+
useStylesScoped$,
10+
useVisibleTask$
11+
} from '@builder.io/qwik';
12+
import styles from './dialog-root.css?inline';
13+
import { DialogRef } from './types';
14+
15+
/**
16+
* Todo-List
17+
* ---------
18+
*
19+
* [ ] Rename Root to ModalRoot
20+
* [ ] Drop dot-Notation. e.g. = Dialog.Root = ModalDialogRoot
21+
* [ ] Rename ref since it is a Qwik reserved word
22+
* [ ] Have a look at Radix-Dialog to get inspired by features/examples
23+
* * What is important for BETA
24+
* * What might be implemented later
25+
* [ ] Think about more tests
26+
*/
27+
28+
export type RootProps = QwikIntrinsicElements['dialog'] & {
29+
fullScreen?: boolean;
30+
dialogRef?: Signal<DialogRef | undefined>;
31+
};
32+
33+
export const Root = component$((props: RootProps) => {
34+
useStylesScoped$(styles);
35+
36+
/** Contains reference to the rendered HTMLDialogElement. */
37+
const dialogElementSig = useSignal<HTMLDialogElement>();
38+
39+
/** Indicates whether the dialog is open. */
40+
const isOpenSig = useSignal(false);
41+
42+
const open$ = $(() => {
43+
const dialog = dialogElementSig.value;
44+
45+
if (!dialog) {
46+
return;
47+
}
48+
dialog.showModal();
49+
isOpenSig.value = true;
50+
});
51+
52+
const close$ = $(() => {
53+
const dialog = dialogElementSig.value;
54+
if (!dialog) {
55+
return;
56+
}
57+
dialog.close();
58+
isOpenSig.value = false;
59+
});
60+
61+
const closeOnBackdropClick$ = $(
62+
(event: QwikMouseEvent<HTMLDialogElement, MouseEvent>) =>
63+
hasDialogBackdropBeenClicked(event) ? close$() : Promise.resolve()
64+
);
65+
66+
/**
67+
*
68+
* Share the public API of the Dialog if the dialog-caller is interested.
69+
*
70+
*/
71+
useVisibleTask$(() => {
72+
if (!props.dialogRef) return;
73+
74+
props.dialogRef.value = { isOpen: isOpenSig, open$, close$ };
75+
});
76+
77+
/**
78+
*
79+
* Lock Scrolling on page when Dialog is opened.
80+
*
81+
*/
82+
useVisibleTask$(({ track }) => {
83+
const isOpened = track(() => isOpenSig.value);
84+
85+
const overflow = isOpened ? 'hidden' : '';
86+
87+
window.document.body.style.overflow = overflow;
88+
});
89+
90+
/**
91+
*
92+
* When dialog is closed by pressing the Escape-Key,
93+
* we set the opened state to false.
94+
*
95+
*/
96+
useVisibleTask$(() => {
97+
const dialog = dialogElementSig.value;
98+
99+
if (!dialog) {
100+
return;
101+
}
102+
103+
dialog.addEventListener('close', () => (isOpenSig.value = false));
104+
});
105+
106+
return (
107+
<dialog
108+
{...props}
109+
class={`${props.class} ${props.fullScreen ? 'full-screen' : ''}`}
110+
ref={dialogElementSig}
111+
onClick$={closeOnBackdropClick$}
112+
>
113+
<Slot />
114+
</dialog>
115+
);
116+
});
117+
118+
function hasDialogBackdropBeenClicked(
119+
event: QwikMouseEvent<HTMLDialogElement, MouseEvent>
120+
) {
121+
const rect = (event.target as HTMLDialogElement).getBoundingClientRect();
122+
123+
return (
124+
rect.left > event.clientX ||
125+
rect.right < event.clientX ||
126+
rect.top > event.clientY ||
127+
rect.bottom < event.clientY
128+
);
129+
}

packages/kit-headless/src/components/dialog/dialog.root.tsx

-88
This file was deleted.

packages/kit-headless/src/components/dialog/types/dialog.root.props.ts

-12
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,27 +0,0 @@
1-
import { QwikMouseEvent } from '@builder.io/qwik';
2-
3-
export function hasDialogBackdropBeenClicked(
4-
event: QwikMouseEvent<HTMLDialogElement, MouseEvent>
5-
) {
6-
const rect = (event.target as HTMLDialogElement).getBoundingClientRect();
7-
8-
return (
9-
rect.left > event.clientX ||
10-
rect.right < event.clientX ||
11-
rect.top > event.clientY ||
12-
rect.bottom < event.clientY
13-
);
14-
}
15-
16-
/**
17-
*
18-
* Throws an error if dialog-Element is not defined, otherwise yielding the dialog.
19-
*
20-
*/
21-
export function ensureDialog(candidate?: HTMLDialogElement): HTMLDialogElement {
22-
if (!candidate) {
23-
throw new Error('[Qwik UI Dialog]: <dialog>-Element not found.');
24-
}
25-
26-
return candidate;
27-
}

0 commit comments

Comments
 (0)