Skip to content

Commit e67d68c

Browse files
committed
more work
1 parent 79706a3 commit e67d68c

File tree

10 files changed

+1336
-30
lines changed

10 files changed

+1336
-30
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<script lang="ts">
2+
import { Dialog as DialogPrimitive, useId } from "bits-ui";
3+
import { box, mergeProps } from "svelte-toolbelt";
4+
import type { DrawerContentProps } from "./types.js";
5+
import { useDrawerContent } from "$lib/vaul.svelte.js";
6+
import { noop } from "$lib/internal/helpers/noop.js";
7+
8+
let {
9+
id = useId(),
10+
ref = $bindable(null),
11+
onMountAutoFocus = noop,
12+
onEscapeKeydown = noop,
13+
onInteractOutside = noop,
14+
onFocusOutside = noop,
15+
...restProps
16+
}: DrawerContentProps = $props();
17+
18+
const contentState = useDrawerContent({
19+
id: box.with(() => id),
20+
ref: box.with(
21+
() => ref,
22+
(v) => (ref = v)
23+
),
24+
});
25+
26+
const mergedProps = $derived(mergeProps(restProps, contentState.props));
27+
</script>
28+
29+
<DialogPrimitive.Content
30+
bind:ref
31+
{...mergedProps}
32+
onMountAutoFocus={(e) => {
33+
onMountAutoFocus(e);
34+
if (e.defaultPrevented) return;
35+
contentState.onMountAutoFocus(e);
36+
}}
37+
onEscapeKeydown={(e) => {
38+
onEscapeKeydown(e);
39+
if (e.defaultPrevented) return;
40+
if (!contentState.root.modal.current) {
41+
e.preventDefault();
42+
}
43+
}}
44+
onFocusOutside={(e) => {
45+
onFocusOutside(e);
46+
if (e.defaultPrevented) return;
47+
if (!contentState.root.modal.current) {
48+
e.preventDefault();
49+
}
50+
}}
51+
onInteractOutside={(e) => {
52+
onInteractOutside(e);
53+
if (e.defaultPrevented) return;
54+
contentState.onInteractOutside(e);
55+
}}
56+
/>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script lang="ts">
2+
import { Dialog as DialogPrimitive, useId } from "bits-ui";
3+
import { box, mergeProps } from "svelte-toolbelt";
4+
import type { DrawerOverlayProps } from "./types.js";
5+
import { useDrawerOverlay } from "$lib/vaul.svelte.js";
6+
7+
let { id = useId(), ref = $bindable(null), ...restProps }: DrawerOverlayProps = $props();
8+
9+
const overlayState = useDrawerOverlay({
10+
id: box.with(() => id),
11+
ref: box.with(
12+
() => ref,
13+
(v) => (ref = v)
14+
),
15+
});
16+
17+
const mergedProps = $derived(mergeProps(restProps, overlayState.props));
18+
</script>
19+
20+
<DialogPrimitive.Overlay bind:ref {...mergedProps} />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
<script lang="ts">
2+
import { Dialog as DialogPrimitive } from "bits-ui";
3+
import { box } from "svelte-toolbelt";
4+
import type { DrawerRootProps } from "./types.js";
5+
import { noop } from "$lib/internal/helpers/noop.js";
6+
import {
7+
DEFAULT_CLOSE_THRESHOLD,
8+
DEFAULT_SCROLL_LOCK_TIMEOUT,
9+
useDrawerRoot,
10+
} from "$lib/vaul.svelte.js";
11+
12+
let {
13+
open = $bindable(false),
14+
onOpenChange = noop,
15+
closeThreshold = DEFAULT_CLOSE_THRESHOLD,
16+
scrollLockTimeout = DEFAULT_SCROLL_LOCK_TIMEOUT,
17+
snapPoints,
18+
fadeFromIndex,
19+
backgroundColor = "black",
20+
nested = false,
21+
shouldScaleBackground = false,
22+
activeSnapPoint = $bindable(null),
23+
onActiveSnapPointChange = noop,
24+
onRelease = noop,
25+
onDrag = noop,
26+
onClose = noop,
27+
dismissible = true,
28+
direction = "bottom",
29+
fixed = false,
30+
handleOnly = false,
31+
noBodyStyles = false,
32+
preventScrollRestoration = true,
33+
...restProps
34+
}: DrawerRootProps = $props();
35+
36+
const rootState = useDrawerRoot({
37+
open: box.with(
38+
() => open,
39+
(v) => {
40+
open = v;
41+
onOpenChange(v);
42+
}
43+
),
44+
closeThreshold: box.with(() => closeThreshold),
45+
scrollLockTimeout: box.with(() => scrollLockTimeout),
46+
snapPoints: box.with(() => snapPoints),
47+
fadeFromIndex: box.with(() => fadeFromIndex),
48+
backgroundColor: box.with(() => backgroundColor),
49+
nested: box.with(() => nested),
50+
shouldScaleBackground: box.with(() => shouldScaleBackground),
51+
activeSnapPoint: box.with(
52+
() => activeSnapPoint,
53+
(v) => {
54+
activeSnapPoint = v;
55+
onActiveSnapPointChange(v);
56+
}
57+
),
58+
onRelease: box.with(() => onRelease),
59+
onDrag: box.with(() => onDrag),
60+
onClose: box.with(() => onClose),
61+
dismissible: box.with(() => dismissible),
62+
direction: box.with(() => direction),
63+
fixed: box.with(() => fixed),
64+
modal: box.with(() => true),
65+
handleOnly: box.with(() => handleOnly),
66+
noBodyStyles: box.with(() => noBodyStyles),
67+
preventScrollRestoration: box.with(() => preventScrollRestoration),
68+
});
69+
</script>
70+
71+
<DialogPrimitive.Root
72+
bind:open
73+
onOpenChange={(o) => {
74+
onOpenChange(o);
75+
if (!o) {
76+
rootState.closeDrawer();
77+
} else if (o) {
78+
rootState.openDrawer();
79+
}
80+
}}
81+
{...restProps}
82+
/>
83+
84+
<style>
85+
:global([data-vaul-drawer]) {
86+
touch-action: none;
87+
transition: transform 0.5s cubic-bezier(0.32, 0.72, 0, 1);
88+
}
89+
90+
:global([data-vaul-drawer][data-vaul-drawer-direction="bottom"]) {
91+
transform: translate3d(0, 100%, 0);
92+
}
93+
94+
:global([data-vaul-drawer][data-vaul-drawer-direction="top"]) {
95+
transform: translate3d(0, -100%, 0);
96+
}
97+
98+
:global([data-vaul-drawer][data-vaul-drawer-direction="left"]) {
99+
transform: translate3d(-100%, 0, 0);
100+
}
101+
102+
:global([data-vaul-drawer][data-vaul-drawer-direction="right"]) {
103+
transform: translate3d(100%, 0, 0);
104+
}
105+
106+
:global(.vaul-dragging .vaul-scrollable [data-vaul-drawer-direction="top"]) {
107+
overflow-y: hidden !important;
108+
}
109+
110+
:global(.vaul-dragging .vaul-scrollable [data-vaul-drawer-direction="bottom"]) {
111+
overflow-y: hidden !important;
112+
}
113+
114+
:global(.vaul-dragging .vaul-scrollable [data-vaul-drawer-direction="left"]) {
115+
overflow-x: hidden !important;
116+
}
117+
:global(.vaul-dragging .vaul-scrollable [data-vaul-drawer-direction="right"]) {
118+
overflow-x: hidden !important;
119+
}
120+
121+
:global([data-vaul-drawer][data-vaul-drawer-visible="true"][data-vaul-drawer-direction="top"]) {
122+
transform: translate3d(0, var(--snap-point-height, 0), 0);
123+
}
124+
125+
:global(
126+
[data-vaul-drawer][data-vaul-drawer-visible="true"][data-vaul-drawer-direction="bottom"]
127+
) {
128+
transform: translate3d(0, var(--snap-point-height, 0), 0);
129+
}
130+
131+
:global(
132+
[data-vaul-drawer][data-vaul-drawer-visible="true"][data-vaul-drawer-direction="left"]
133+
) {
134+
transform: translate3d(var(--snap-point-height, 0), 0, 0);
135+
}
136+
137+
:global(
138+
[data-vaul-drawer][data-vaul-drawer-visible="true"][data-vaul-drawer-direction="right"]
139+
) {
140+
transform: translate3d(var(--snap-point-height, 0), 0, 0);
141+
}
142+
143+
:global([data-vaul-overlay]) {
144+
opacity: 0;
145+
transition: opacity 0.5s cubic-bezier(0.32, 0.72, 0, 1);
146+
}
147+
148+
:global([data-vaul-overlay][data-vaul-drawer-visible="true"]) {
149+
opacity: 1;
150+
}
151+
152+
:global([data-vaul-drawer]::after) {
153+
content: "";
154+
position: absolute;
155+
background: inherit;
156+
background-color: inherit;
157+
}
158+
159+
:global([data-vaul-drawer][data-vaul-drawer-direction="top"]::after) {
160+
top: initial;
161+
bottom: 100%;
162+
left: 0;
163+
right: 0;
164+
height: 200%;
165+
}
166+
167+
:global([data-vaul-drawer][data-vaul-drawer-direction="bottom"]::after) {
168+
top: 100%;
169+
bottom: initial;
170+
left: 0;
171+
right: 0;
172+
height: 200%;
173+
}
174+
175+
:global([data-vaul-drawer][data-vaul-drawer-direction="left"]::after) {
176+
left: initial;
177+
right: 100%;
178+
top: 0;
179+
bottom: 0;
180+
width: 200%;
181+
}
182+
183+
:global([data-vaul-drawer][data-vaul-drawer-direction="right"]::after) {
184+
left: 100%;
185+
right: initial;
186+
top: 0;
187+
bottom: 0;
188+
width: 200%;
189+
}
190+
191+
:global(
192+
[data-vaul-overlay][data-vaul-snap-points="true"]:not(
193+
[data-vaul-snap-points-overlay="true"]
194+
):not([data-state="closed"])
195+
) {
196+
opacity: 0;
197+
}
198+
199+
:global(
200+
[data-vaul-overlay][data-vaul-snap-points-overlay="true"]:not(
201+
[data-vaul-drawer-visible="false"]
202+
)
203+
) {
204+
opacity: 1;
205+
}
206+
207+
/* This will allow us to not animate via animation, but still benefit from delaying
208+
unmount via Bits */
209+
@keyframes -global-fake-animation {
210+
from {
211+
}
212+
to {
213+
}
214+
}
215+
216+
@media (hover: hover) and (pointer: fine) {
217+
:global([data-vaul-drawer]) {
218+
user-select: none;
219+
}
220+
}
221+
</style>

packages/vaul-svelte/src/lib/components/index.ts

Whitespace-only changes.

0 commit comments

Comments
 (0)