radix_leptos_primitives/components/
sheet.rs1use crate::utils::merge_classes;
2use leptos::callback::Callback;
3use leptos::children::Children;
4use leptos::prelude::*;
5
6#[derive(Debug, Clone, Copy, PartialEq)]
62pub enum SheetVariant {
63 Default,
64 Destructive,
65 Success,
66 Warning,
67 Info,
68}
69
70#[derive(Debug, Clone, Copy, PartialEq)]
71pub enum SheetPosition {
72 Left,
73 Right,
74 Top,
75 Bottom,
76}
77
78#[derive(Debug, Clone, Copy, PartialEq)]
79pub enum SheetSize {
80 Small,
81 Medium,
82 Large,
83 ExtraLarge,
84 Full,
85}
86
87impl SheetVariant {
88 pub fn as_str(&self) -> &'static str {
89 match self {
90 SheetVariant::Default => "default",
91 SheetVariant::Destructive => "destructive",
92 SheetVariant::Success => "success",
93 SheetVariant::Warning => "warning",
94 SheetVariant::Info => "info",
95 }
96 }
97}
98
99impl SheetPosition {
100 pub fn as_str(&self) -> &'static str {
101 match self {
102 SheetPosition::Left => "left",
103 SheetPosition::Right => "right",
104 SheetPosition::Top => "top",
105 SheetPosition::Bottom => "bottom",
106 }
107 }
108}
109
110impl SheetSize {
111 pub fn as_str(&self) -> &'static str {
112 match self {
113 SheetSize::Small => "sm",
114 SheetSize::Medium => "md",
115 SheetSize::Large => "lg",
116 SheetSize::ExtraLarge => "xl",
117 SheetSize::Full => "full",
118 }
119 }
120}
121
122#[component]
124pub fn Sheet(
125 #[prop(optional)] class: Option<String>,
126 #[prop(optional)] style: Option<String>,
127 #[prop(optional)] children: Option<Children>,
128 #[prop(optional)] open: Option<bool>,
129 #[prop(optional)] position: Option<SheetPosition>,
130 #[prop(optional)] size: Option<SheetSize>,
131 #[prop(optional)] onopen_change: Option<Callback<bool>>,
132) -> impl IntoView {
133 let open = open.unwrap_or(false);
134 let position = position.unwrap_or(SheetPosition::Right);
135 let size = size.unwrap_or(SheetSize::Medium);
136 let onopen_change = onopen_change.unwrap_or_else(|| Callback::new(|_| {}));
137
138 let class = merge_classes(vec!["sheet", position.as_str(), size.as_str()].to_vec());
139}
140
141#[component]
143pub fn SheetContent(
144 #[prop(optional)] class: Option<String>,
145 #[prop(optional)] style: Option<String>,
146 #[prop(optional)] children: Option<Children>,
147) -> impl IntoView {
148 let class = merge_classes(vec!["sheet-content", class.as_deref().unwrap_or("")].to_vec());
149
150 view! {
151 <div
152 class=class
153 style=style
154 >
155 {children.map(|c| c())}
156 </div>
157 }
158}
159
160#[component]
162pub fn SheetHeader(
163 #[prop(optional)] class: Option<String>,
164 #[prop(optional)] style: Option<String>,
165 #[prop(optional)] children: Option<Children>,
166) -> impl IntoView {
167 let class = merge_classes(vec!["sheet-header", class.as_deref().unwrap_or("")].to_vec());
168
169 view! {
170 <div
171 class=class
172 style=style
173 >
174 {children.map(|c| c())}
175 </div>
176 }
177}
178
179#[component]
181pub fn SheetTitle(
182 #[prop(optional)] class: Option<String>,
183 #[prop(optional)] style: Option<String>,
184 #[prop(optional)] children: Option<Children>,
185) -> impl IntoView {
186 let class = merge_classes(vec!["sheet-title", class.as_deref().unwrap_or("")].to_vec());
187
188 view! {
189 <h2
190 class=class
191 style=style
192 >
193 {children.map(|c| c())}
194 </h2>
195 }
196}
197
198#[component]
200pub fn SheetDescription(
201 #[prop(optional)] class: Option<String>,
202 #[prop(optional)] style: Option<String>,
203 #[prop(optional)] children: Option<Children>,
204) -> impl IntoView {
205 let class = merge_classes(vec!["sheet-description", class.as_deref().unwrap_or("")].to_vec());
206
207 view! {
208 <p
209 class=class
210 style=style
211 >
212 {children.map(|c| c())}
213 </p>
214 }
215}
216
217#[component]
219pub fn SheetBody(
220 #[prop(optional)] class: Option<String>,
221 #[prop(optional)] style: Option<String>,
222 #[prop(optional)] children: Option<Children>,
223) -> impl IntoView {
224 let class = merge_classes(vec!["sheet-body", class.as_deref().unwrap_or("")].to_vec());
225
226 view! {
227 <div
228 class=class
229 style=style
230 >
231 {children.map(|c| c())}
232 </div>
233 }
234}
235
236#[component]
238pub fn SheetFooter(
239 #[prop(optional)] class: Option<String>,
240 #[prop(optional)] style: Option<String>,
241 #[prop(optional)] children: Option<Children>,
242) -> impl IntoView {
243 let class = merge_classes(vec!["sheet-footer", class.as_deref().unwrap_or("")].to_vec());
244
245 view! {
246 <div
247 class=class
248 style=style
249 >
250 {children.map(|c| c())}
251 </div>
252 }
253}
254
255#[component]
257pub fn SheetClose(
258 #[prop(optional)] class: Option<String>,
259 #[prop(optional)] style: Option<String>,
260 #[prop(optional)] children: Option<Children>,
261 #[prop(optional)] on_click: Option<Callback<()>>,
262) -> impl IntoView {
263 let on_click = on_click.unwrap_or_else(|| Callback::new(|_| {}));
264
265 let class = merge_classes(vec!["sheet-close", class.as_deref().unwrap_or("")].to_vec());
266
267 view! {
268 <button
269 class=class
270 style=style
271 on:click=move |_| on_click.run(())
272 aria-label="Close sheet"
273 >
274 {children.map(|c| c())}
275 </button>
276 }
277}
278
279#[cfg(test)]
280mod tests {
281 use proptest::prelude::*;
282
283 #[test]
284 fn test_sheet_component_creation() {}
285
286 #[test]
287 fn test_sheet_with_position_component_creation() {}
288
289 proptest! {
290 #[test]
291 fn test_sheet_props(___class in ".*", ___style in ".*") {
292
293 }
294
295 #[test]
296 fn test_sheetopen_state(__open: bool, ___position_index in 0..4usize, ___size_index in 0..5usize) {
297
298 }
299
300 #[test]
301 fn test_sheet_positions(___position_index in 0..4usize) {
302
303 }
304
305 #[test]
306 fn test_sheet_sizes(___size_index in 0..5usize) {
307
308 }
309
310 #[test]
311 fn test_sheet_content_props(___class in ".*", ___style in ".*") {
312
313 }
314
315 #[test]
316 fn test_sheet_header_props(___class in ".*", ___style in ".*") {
317
318 }
319
320 #[test]
321 fn test_sheet_title_props(___class in ".*", ___style in ".*") {
322
323 }
324
325 #[test]
326 fn test_sheet_description_props(___class in ".*", ___style in ".*") {
327
328 }
329
330 #[test]
331 fn test_sheet_body_props(___class in ".*", ___style in ".*") {
332
333 }
334
335 #[test]
336 fn test_sheet_footer_props(___class in ".*", ___style in ".*") {
337
338 }
339
340 #[test]
341 fn test_sheet_close_props(___class in ".*", ___style in ".*") {
342
343 }
344 }
345}