aspect_ratio.rs
1 use crate::use_unique_id; 2 use dioxus::html::GlobalAttributesExtension; 3 use dioxus::prelude::*; 4 use dioxus_primitives::aspect_ratio::AspectRatio as PrimitiveAspectRatio; 5 6 /// Props for the AspectRatio component 7 #[derive(Props, Clone, PartialEq)] 8 pub struct AspectRatioProps { 9 /// The aspect ratio (width / height) 10 pub ratio: f64, 11 12 /// Optional ID for the aspect ratio container 13 #[props(default)] 14 pub id: Option<String>, 15 16 /// Optional class name for additional styling 17 #[props(default)] 18 pub class: Option<String>, 19 20 /// Children to render inside the aspect ratio container 21 pub children: Element, 22 } 23 24 /// A styled aspect ratio container that maintains consistent proportions 25 #[component] 26 pub fn AspectRatio(props: AspectRatioProps) -> Element { 27 // Generate unique ID if not provided 28 let aspect_ratio_id = use_unique_id(); 29 let id_value = use_memo(move || { 30 props 31 .id 32 .clone() 33 .unwrap_or_else(|| aspect_ratio_id.peek().clone()) 34 }); 35 36 // Build classes - combining default styling with optional custom classes 37 let full_classes = vec![ 38 // Base classes 39 "relative w-full overflow-hidden", 40 // Additional classes passed by the user 41 props.class.as_deref().unwrap_or(""), 42 ] 43 .into_iter() 44 .filter(|s| !s.is_empty()) 45 .collect::<Vec<_>>() 46 .join(" "); 47 48 rsx! { 49 PrimitiveAspectRatio { 50 id: id_value.peek().clone(), 51 class: full_classes, 52 ratio: props.ratio, 53 54 {props.children} 55 } 56 } 57 }