Skip to content

Commit 26843e6

Browse files
committed
drawer: restore external CSS and tighten vaul parity
Move drawer styles back to public/components/vaul_drawer.css and load it from shell. Remove inline style constant, keep animate/drag behavior aligned with the original vaul runtime, and fix timeout typing cleanup.
1 parent 6310eae commit 26843e6

4 files changed

Lines changed: 134 additions & 139 deletions

File tree

app/src/shell.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ pub fn shell(options: LeptosOptions) -> impl IntoView {
138138
<noscript>
139139
<link rel="stylesheet" href="/components/sonner.css" />
140140
</noscript>
141+
<link rel="preload" href="/components/vaul_drawer.css" r#as="style" />
142+
<link rel="stylesheet" href="/components/vaul_drawer.css" media="print" onload="this.media='all'" />
141143

142144
// Load scripts (async for non-blocking parallel download, executes as soon as ready)
143145
<script async src="/components/resizable.bundle.js"></script>

app_crates/registry/src/ui/drawer.rs

Lines changed: 2 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -16,142 +16,9 @@ const TRANSITION_EASING: &str = "cubic-bezier(0.32, 0.72, 0, 1)";
1616
const WINDOW_TOP_OFFSET: f64 = 26.0;
1717
const BORDER_RADIUS: f64 = 8.0;
1818
const WRAPPER_TRANSLATE_Y: f64 = 14.0;
19-
const SCROLL_LOCK_TIMEOUT_MS: f64 = 500.0;
19+
const SCROLL_LOCK_TIMEOUT_MS: u32 = 500;
2020
const FOCUS_DELAY_MS: u64 = 100;
2121

22-
const DRAWER_STYLE: &str = r#"
23-
[data-vaul-drawer] {
24-
touch-action: none;
25-
will-change: transform;
26-
transition: transform 0.5s cubic-bezier(0.32, 0.72, 0, 1);
27-
animation-duration: 0.5s;
28-
animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
29-
}
30-
31-
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Bottom'][data-state='open'] {
32-
animation-name: slideFromBottom;
33-
}
34-
35-
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Bottom'][data-state='closed'] {
36-
animation-name: slideToBottom;
37-
}
38-
39-
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Left'][data-state='open'] {
40-
animation-name: slideFromLeft;
41-
}
42-
43-
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Left'][data-state='closed'] {
44-
animation-name: slideToLeft;
45-
}
46-
47-
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Right'][data-state='open'] {
48-
animation-name: slideFromRight;
49-
}
50-
51-
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Right'][data-state='closed'] {
52-
animation-name: slideToRight;
53-
}
54-
55-
[data-vaul-overlay][data-vaul-snap-points='false'] {
56-
animation-duration: 0.5s;
57-
animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
58-
}
59-
60-
[data-vaul-overlay][data-vaul-snap-points='false'][data-state='open'] {
61-
animation-name: fadeIn;
62-
}
63-
64-
[data-vaul-overlay][data-state='closed'] {
65-
animation-name: fadeOut;
66-
}
67-
68-
[data-vaul-animate='false'] {
69-
animation: none !important;
70-
}
71-
72-
[data-vaul-drawer]:not([data-vaul-variant='Floating'])::after {
73-
content: '';
74-
position: absolute;
75-
background: inherit;
76-
background-color: inherit;
77-
}
78-
79-
[data-vaul-drawer][data-vaul-drawer-position='Bottom']::after {
80-
top: 100%;
81-
left: 0;
82-
right: 0;
83-
height: 200%;
84-
}
85-
86-
[data-vaul-drawer][data-vaul-drawer-position='Left']::after {
87-
right: 100%;
88-
top: 0;
89-
bottom: 0;
90-
width: 200%;
91-
}
92-
93-
[data-vaul-drawer][data-vaul-drawer-position='Right']::after {
94-
left: 100%;
95-
top: 0;
96-
bottom: 0;
97-
width: 200%;
98-
}
99-
100-
[data-vaul-handle] {
101-
touch-action: pan-y;
102-
}
103-
104-
[data-vaul-handle-hitarea] {
105-
position: absolute;
106-
left: 50%;
107-
top: 50%;
108-
transform: translate(-50%, -50%);
109-
width: max(100%, 2.75rem);
110-
height: max(100%, 2.75rem);
111-
touch-action: inherit;
112-
}
113-
114-
[data-vaul-variant='Floating'][data-vaul-drawer-position='Right'][data-state='closed'] {
115-
transform: translate3d(calc(100% + 8px), 0, 0);
116-
}
117-
118-
@keyframes fadeIn {
119-
from { opacity: 0; }
120-
to { opacity: 1; }
121-
}
122-
123-
@keyframes fadeOut {
124-
to { opacity: 0; }
125-
}
126-
127-
@keyframes slideFromBottom {
128-
from { transform: translate3d(0, var(--initial-transform, 100%), 0); }
129-
to { transform: translate3d(0, 0, 0); }
130-
}
131-
132-
@keyframes slideToBottom {
133-
to { transform: translate3d(0, var(--initial-transform, 100%), 0); }
134-
}
135-
136-
@keyframes slideFromLeft {
137-
from { transform: translate3d(calc(var(--initial-transform, 100%) * -1), 0, 0); }
138-
to { transform: translate3d(0, 0, 0); }
139-
}
140-
141-
@keyframes slideToLeft {
142-
to { transform: translate3d(calc(var(--initial-transform, 100%) * -1), 0, 0); }
143-
}
144-
145-
@keyframes slideFromRight {
146-
from { transform: translate3d(var(--initial-transform, 100%), 0, 0); }
147-
to { transform: translate3d(0, 0, 0); }
148-
}
149-
150-
@keyframes slideToRight {
151-
to { transform: translate3d(var(--initial-transform, 100%), 0, 0); }
152-
}
153-
"#;
154-
15522
mod components {
15623
use super::*;
15724
clx! {DrawerBody, div, "flex flex-col gap-4 mx-auto max-w-[500px]"}
@@ -294,8 +161,6 @@ pub fn Drawer(
294161
};
295162

296163
view! {
297-
<style>{DRAWER_STYLE}</style>
298-
299164
<div
300165
node_ref=overlay_ref
301166
data-name="DrawerOverlay"
@@ -753,7 +618,7 @@ fn should_drag(
753618
}
754619

755620
if let Some(last_prevented) = last_time_drag_prevented.get_untracked()
756-
&& current_time - last_prevented < SCROLL_LOCK_TIMEOUT_MS
621+
&& current_time - last_prevented < f64::from(SCROLL_LOCK_TIMEOUT_MS)
757622
{
758623
last_time_drag_prevented.set(Some(current_time));
759624
return false;

public/components/vaul_drawer.css

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
[data-vaul-drawer] {
2+
touch-action: none;
3+
will-change: transform;
4+
transition: transform 0.5s cubic-bezier(0.32, 0.72, 0, 1);
5+
animation-duration: 0.5s;
6+
animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
7+
}
8+
9+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Bottom'][data-state='open'] {
10+
animation-name: slideFromBottom;
11+
}
12+
13+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Bottom'][data-state='closed'] {
14+
animation-name: slideToBottom;
15+
}
16+
17+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Left'][data-state='open'] {
18+
animation-name: slideFromLeft;
19+
}
20+
21+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Left'][data-state='closed'] {
22+
animation-name: slideToLeft;
23+
}
24+
25+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Right'][data-state='open'] {
26+
animation-name: slideFromRight;
27+
}
28+
29+
[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-position='Right'][data-state='closed'] {
30+
animation-name: slideToRight;
31+
}
32+
33+
[data-vaul-overlay][data-vaul-snap-points='false'] {
34+
animation-duration: 0.5s;
35+
animation-timing-function: cubic-bezier(0.32, 0.72, 0, 1);
36+
}
37+
38+
[data-vaul-overlay][data-vaul-snap-points='false'][data-state='open'] {
39+
animation-name: fadeIn;
40+
}
41+
42+
[data-vaul-overlay][data-state='closed'] {
43+
animation-name: fadeOut;
44+
}
45+
46+
[data-vaul-animate='false'] {
47+
animation: none !important;
48+
}
49+
50+
[data-vaul-drawer]:not([data-vaul-variant='Floating'])::after {
51+
content: '';
52+
position: absolute;
53+
background: inherit;
54+
background-color: inherit;
55+
}
56+
57+
[data-vaul-drawer][data-vaul-drawer-position='Bottom']::after {
58+
top: 100%;
59+
left: 0;
60+
right: 0;
61+
height: 200%;
62+
}
63+
64+
[data-vaul-drawer][data-vaul-drawer-position='Left']::after {
65+
right: 100%;
66+
top: 0;
67+
bottom: 0;
68+
width: 200%;
69+
}
70+
71+
[data-vaul-drawer][data-vaul-drawer-position='Right']::after {
72+
left: 100%;
73+
top: 0;
74+
bottom: 0;
75+
width: 200%;
76+
}
77+
78+
[data-vaul-handle] {
79+
touch-action: pan-y;
80+
}
81+
82+
[data-vaul-handle-hitarea] {
83+
position: absolute;
84+
left: 50%;
85+
top: 50%;
86+
transform: translate(-50%, -50%);
87+
width: max(100%, 2.75rem);
88+
height: max(100%, 2.75rem);
89+
touch-action: inherit;
90+
}
91+
92+
[data-vaul-variant='Floating'][data-vaul-drawer-position='Right'][data-state='closed'] {
93+
transform: translate3d(calc(100% + 8px), 0, 0);
94+
}
95+
96+
@keyframes fadeIn {
97+
from { opacity: 0; }
98+
to { opacity: 1; }
99+
}
100+
101+
@keyframes fadeOut {
102+
to { opacity: 0; }
103+
}
104+
105+
@keyframes slideFromBottom {
106+
from { transform: translate3d(0, var(--initial-transform, 100%), 0); }
107+
to { transform: translate3d(0, 0, 0); }
108+
}
109+
110+
@keyframes slideToBottom {
111+
to { transform: translate3d(0, var(--initial-transform, 100%), 0); }
112+
}
113+
114+
@keyframes slideFromLeft {
115+
from { transform: translate3d(calc(var(--initial-transform, 100%) * -1), 0, 0); }
116+
to { transform: translate3d(0, 0, 0); }
117+
}
118+
119+
@keyframes slideToLeft {
120+
to { transform: translate3d(calc(var(--initial-transform, 100%) * -1), 0, 0); }
121+
}
122+
123+
@keyframes slideFromRight {
124+
from { transform: translate3d(var(--initial-transform, 100%), 0, 0); }
125+
to { transform: translate3d(0, 0, 0); }
126+
}
127+
128+
@keyframes slideToRight {
129+
to { transform: translate3d(var(--initial-transform, 100%), 0, 0); }
130+
}

public/registry/styles/default/drawer.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,6 @@ pub fn Drawer(
149149
});
150150

151151
view! {
152-
<style>{DRAWER_STYLE}</style>
153-
154152
<div
155153
data-name="DrawerOverlay"
156154
node_ref=overlay_ref

0 commit comments

Comments
 (0)