/ libs / ui / src / components / aspect_ratio.rs
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  }