Skip to content

Commit 53a1305

Browse files
committed
feat(dialog): introduce DialogPositioner for improved layout and scroll behavior
1 parent c6d07d0 commit 53a1305

41 files changed

Lines changed: 1111 additions & 167 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/showcase/demo/headless/dialog/basic-demo.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as React from 'react';
77
import { createPortal } from 'react-dom';
88

99
export default function BasicDemo() {
10-
const { triggerProps, backdropProps, backdropMotionProps, popupProps, closeProps, headerProps, contentProps, rootProps, state } = useDialog();
10+
const { triggerProps, backdropProps, positionerProps, popupProps, closeProps, headerProps, contentProps, rootProps, state } = useDialog();
1111
const portal = usePortal();
1212

1313
const popupRef = React.useRef<HTMLDivElement>(null);
@@ -24,9 +24,10 @@ export default function BasicDemo() {
2424
leaveToClassName: 'opacity-0 scale-75'
2525
});
2626

27+
const backdropRef = React.useRef<HTMLDivElement>(null);
2728
const backdropMotion = useMotion({
28-
...backdropMotionProps.motionProps,
29-
visible: backdropMotionProps.visible,
29+
elementRef: backdropRef,
30+
visible: state.open,
3031
enterFromClassName: 'opacity-0',
3132
enterActiveClassName: 'transition-opacity duration-150',
3233
enterToClassName: 'opacity-100',
@@ -48,12 +49,13 @@ export default function BasicDemo() {
4849
popupMotion.state.rendered &&
4950
createPortal(
5051
<div className="fixed inset-0 z-1100">
51-
{backdropMotion.state.rendered && <div {...backdropProps} className="fixed inset-0 bg-black/50" />}
52+
{backdropMotion.state.rendered && <div {...backdropProps} ref={backdropRef} className="fixed inset-0 bg-black/50" />}
53+
<div {...positionerProps} className="fixed inset-0 flex items-center justify-center p-8 pointer-events-none">
5254
{popupMotion.state.rendered && (
5355
<div
5456
{...popupProps}
5557
ref={popupRef}
56-
className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[28rem] max-w-[90vw] max-h-[90vh] bg-surface-0 dark:bg-surface-900 rounded-xl shadow-2xl flex flex-col border border-surface-200 dark:border-surface-700 z-50"
58+
className="w-[28rem] max-w-[90vw] max-h-full bg-surface-0 dark:bg-surface-900 rounded-xl shadow-2xl flex flex-col border border-surface-200 dark:border-surface-700 pointer-events-auto"
5759
>
5860
<div {...headerProps} className="flex items-center justify-between p-5">
5961
<span className="text-lg font-semibold">Edit Profile</span>
@@ -112,6 +114,7 @@ export default function BasicDemo() {
112114
</div>
113115
</div>
114116
)}
117+
</div>
115118
</div>,
116119
document.body
117120
)}

apps/showcase/demo/primitive/dialog/basic-demo.module.css

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,28 @@
3535
background-color: rgba(0, 0, 0, 0.5);
3636
}
3737

38-
.popup {
38+
.positioner {
3939
position: fixed;
40-
top: 50%;
41-
left: 50%;
42-
translate: -50% -50%;
40+
inset: 0;
41+
display: flex;
42+
align-items: center;
43+
justify-content: center;
44+
padding: 2rem;
45+
pointer-events: none;
46+
z-index: 50;
47+
}
48+
49+
.popup {
4350
width: 28rem;
4451
max-width: 90vw;
45-
max-height: 90vh;
52+
max-height: 100%;
4653
background-color: light-dark(var(--p-surface-0), var(--p-surface-900));
4754
border: 1px solid var(--p-content-border-color);
4855
border-radius: 0.75rem;
4956
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
5057
display: flex;
5158
flex-direction: column;
52-
z-index: 50;
59+
pointer-events: auto;
5360
}
5461

5562
.header {

apps/showcase/demo/primitive/dialog/basic-demo.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ export default function BasicDemo() {
1010
<Dialog.Trigger className={styles.trigger}>Edit Profile</Dialog.Trigger>
1111
<Dialog.Portal>
1212
<Dialog.Backdrop className={styles.backdrop} />
13-
<Dialog.Popup className={styles.popup}>
13+
<Dialog.Positioner className={styles.positioner}>
14+
<Dialog.Popup className={styles.popup}>
1415
<Dialog.Header className={styles.header}>
1516
<Dialog.Title className={styles.title}>Edit Profile</Dialog.Title>
1617
<Dialog.HeaderActions>
@@ -45,7 +46,8 @@ export default function BasicDemo() {
4546
</div>
4647
</div>
4748
</Dialog.Content>
48-
</Dialog.Popup>
49+
</Dialog.Popup>
50+
</Dialog.Positioner>
4951
</Dialog.Portal>
5052
</Dialog.Root>
5153
</div>

apps/showcase/demo/styled/commandmenu/with-dialog-demo.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export default function BasicDemo() {
2828
</Dialog.Trigger>
2929
<Dialog.Portal>
3030
<Dialog.Backdrop />
31+
<Dialog.Positioner>
3132
<Dialog.Popup className="overflow-hidden max-w-md w-full">
3233
<CommandMenu.Root
3334
className="rounded-none border-none"
@@ -83,6 +84,7 @@ export default function BasicDemo() {
8384
</CommandMenu.Footer>
8485
</CommandMenu.Root>
8586
</Dialog.Popup>
87+
</Dialog.Positioner>
8688
</Dialog.Portal>
8789
</Dialog.Root>
8890
</div>

apps/showcase/demo/styled/dialog/basic-demo.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export default function BasicDemo() {
1313
<Dialog.Trigger as={Button}>Edit Profile</Dialog.Trigger>
1414
<Dialog.Portal>
1515
<Dialog.Backdrop />
16+
<Dialog.Positioner>
1617
<Dialog.Popup style={{ width: '28rem' }}>
1718
<Dialog.Header>
1819
<Dialog.Title>Edit Profile</Dialog.Title>
@@ -61,6 +62,7 @@ export default function BasicDemo() {
6162
</div>
6263
</Dialog.Content>
6364
</Dialog.Popup>
65+
</Dialog.Positioner>
6466
</Dialog.Portal>
6567
</Dialog.Root>
6668
</div>

apps/showcase/demo/styled/dialog/confirmation-demo.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default function ConfirmationDemo() {
1111
</Dialog.Trigger>
1212
<Dialog.Portal>
1313
<Dialog.Backdrop />
14+
<Dialog.Positioner>
1415
<Dialog.Popup style={{ width: '26rem' }}>
1516
<Dialog.Header>
1617
<Dialog.Title>Delete your account.</Dialog.Title>
@@ -32,6 +33,7 @@ export default function ConfirmationDemo() {
3233
</div>
3334
</Dialog.Content>
3435
</Dialog.Popup>
36+
</Dialog.Positioner>
3537
</Dialog.Portal>
3638
</Dialog.Root>
3739
</div>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
'use client';
2+
import { Times } from '@primeicons/react/times';
3+
import { Button } from '@primereact/ui/button';
4+
import { Dialog } from '@primereact/ui/dialog';
5+
6+
export default function DraggableDemo() {
7+
return (
8+
<div className="flex justify-center">
9+
<Dialog.Root draggable>
10+
<Dialog.Trigger as={Button}>Open Note</Dialog.Trigger>
11+
<Dialog.Portal>
12+
<Dialog.Backdrop />
13+
<Dialog.Positioner>
14+
<Dialog.Popup style={{ width: '24rem' }}>
15+
<Dialog.Header>
16+
<Dialog.Title>Quick Note</Dialog.Title>
17+
<Dialog.HeaderActions>
18+
<Dialog.Close as={Button} iconOnly variant="text" rounded severity="secondary">
19+
<Times />
20+
</Dialog.Close>
21+
</Dialog.HeaderActions>
22+
</Dialog.Header>
23+
<Dialog.Content>
24+
<div className="flex flex-col gap-4">
25+
<p className="text-sm text-surface-500 dark:text-surface-400 mt-0 mb-0">Drag this dialog by its header to reposition it anywhere on the screen.</p>
26+
<textarea
27+
className="w-full h-32 p-3 rounded-md border border-surface-200 dark:border-surface-700 bg-surface-0 dark:bg-surface-900 text-surface-700 dark:text-surface-0 text-sm resize-none focus:outline-none focus:ring-2 focus:ring-primary-500"
28+
placeholder="Type your note here..."
29+
defaultValue="Remember to review the design specs for the new dashboard layout before the meeting tomorrow."
30+
/>
31+
</div>
32+
</Dialog.Content>
33+
<Dialog.Footer>
34+
<Dialog.Close as={Button} severity="secondary">
35+
Discard
36+
</Dialog.Close>
37+
<Dialog.Close as={Button}>Save Note</Dialog.Close>
38+
</Dialog.Footer>
39+
</Dialog.Popup>
40+
</Dialog.Positioner>
41+
</Dialog.Portal>
42+
</Dialog.Root>
43+
</div>
44+
);
45+
}

apps/showcase/demo/styled/dialog/fullscreen-demo.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export default function FullScreenDemo() {
1212
<Dialog.Trigger as={Button}>View Gallery</Dialog.Trigger>
1313
<Dialog.Portal>
1414
<Dialog.Backdrop />
15+
<Dialog.Positioner>
1516
<Dialog.Popup>
1617
<Dialog.Header>
1718
<Dialog.Title>Photo Gallery</Dialog.Title>
@@ -37,6 +38,7 @@ export default function FullScreenDemo() {
3738
</div>
3839
</Dialog.Content>
3940
</Dialog.Popup>
41+
</Dialog.Positioner>
4042
</Dialog.Portal>
4143
</Dialog.Root>
4244
</div>

0 commit comments

Comments
 (0)